Fighting client-side caching in Django
You can achieve this using the cache_control decorator. Example from the documentation:
from django.views.decorators.cache import never_cache@never_cachedef myview(request): # ...
This approach (slight modification of L. De Leo's solution) with a custom middleware has worked well for me as a site wide solution:
from django.utils.cache import add_never_cache_headersclass DisableClientSideCachingMiddleware(object): def process_response(self, request, response): add_never_cache_headers(response) return response
This makes use of add_never_cache_headers
.
If you want to combine this with UpdateCacheMiddleware
and FetchFromCacheMiddleware
, to enable server-side caching while disabling client-side caching, you need to add DisableClientSideCachingMiddleware
before everything else, like this:
MIDDLEWARE_CLASSES = ( 'custom.middleware.DisableClientSideCachingMiddleware', 'django.middleware.cache.UpdateCacheMiddleware', # ... all other middleware ... 'django.middleware.cache.FetchFromCacheMiddleware',)
To supplement existing answers. Here is a decorator that adds additional headers to disable caching:
from django.views.decorators.cache import patch_cache_controlfrom functools import wrapsdef never_ever_cache(decorated_function): """Like Django @never_cache but sets more valid cache disabling headers. @never_cache only sets Cache-Control:max-age=0 which is not enough. For example, with max-axe=0 Firefox returns cached results of GET calls when it is restarted. """ @wraps(decorated_function) def wrapper(*args, **kwargs): response = decorated_function(*args, **kwargs) patch_cache_control( response, no_cache=True, no_store=True, must_revalidate=True, max_age=0) return response return wrapper
And you can use it like:
class SomeView(View): @method_decorator(never_ever_cache) def get(self, request): return HttpResponse('Hello')