103👍
You can achieve this using the cache_control decorator. Example from the documentation:
from django.views.decorators.cache import never_cache
@never_cache
def myview(request):
# ...
56👍
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_headers
class 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',
)
- [Django]-Django filter many-to-many with contains
- [Django]-Django admin TabularInline – is there a good way of adding a custom html column?
- [Django]-Django override save for model only in some cases?
17👍
To supplement existing answers. Here is a decorator that adds additional headers to disable caching:
from django.views.decorators.cache import patch_cache_control
from functools import wraps
def 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')
- [Django]-CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False
- [Django]-Django filter queryset __in for *every* item in list
- [Django]-How do I access the request object or any other variable in a form's clean() method?
11👍
I was scratching my head when the three magic meta
didn’t work in Firefox and Safari.
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
Apparently it can happen because some browsers will ignore the client side meta
, so it should be handled at server side.
I tried all the answers from this post for my class based views (django==1.11.6
). But referring to answers from @Lorenzo and @Zags, I decided to write a middleware which I think is a simple one.
So adding to other good answers,
# middleware.py
class DisableBrowserCacheMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
response['Pragma'] = 'no-cache'
response['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response['Expires'] = '0'
return response
# settings.py
MIDDLEWARE = [
'myapp.middleware.DisableBrowserCacheMiddleware',
...
- [Django]-Using JSON in django template
- [Django]-Django FileField upload is not working for me
- [Django]-Django template includes slow?
8👍
Actually writing my own middleware was easy enough:
from django.http import HttpResponse
class NoCacheMiddleware(object):
def process_response(self, request, response):
response['Pragma'] = 'no-cache'
response['Cache-Control'] = 'no-cache must-revalidate proxy-revalidate'
return response
Still doesn’t really behave like i wanted but so neither does the @never_cache decorator
- [Django]-Check for pending Django migrations
- [Django]-Where's my JSON data in my incoming Django request?
- [Django]-Why does django's prefetch_related() only work with all() and not filter()?
7👍
Regarding the Google Chrome browser (Version 34.0.1847.116 m) and the other browsers, I found that only the @cache_control
decorator is working. I use Django 1.6.2.
Use it like this:
@cache_control(max_age=0, no_cache=True, no_store=True, must_revalidate=True)
def view(request):
...
- [Django]-How to get an ImageField URL within a template?
- [Django]-Unable to perform collectstatic
- [Django]-Django/DRF – 405 Method not allowed on DELETE operation
6👍
Here is a rewrite of @Meilo’s answer for Django 1.10+:
from django.utils.cache import add_never_cache_headers
class DisableClientCachingMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
add_never_cache_headers(response)
return response
- [Django]-Django auto_now and auto_now_add
- [Django]-Python NameError: name 'include' is not defined
- [Django]-Django self-referential foreign key
0👍
For Django 4+:
from django.utils.cache import add_never_cache_headers
def disable_client_side_caching_middleware(get_response):
def middleware(request):
response = get_response(request)
add_never_cache_headers(response)
return response
return middleware
MIDDLEWARE_CLASSES = (
...
'my_app.middleware.disable_client_side_caching_middleware'
...
)
- [Django]-Django: Open uploaded file while still in memory; In the Form Clean method?
- [Django]-How to access request body when using Django Rest Framework and avoid getting RawPostDataException
- [Django]-What is reverse()?
0👍
For anyone with newer version of Django 4.0+
class DisableClientSideCachingMiddleware:
"""
Middleware to disable client side caching, that is on browser.
Adds a Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private header ,
to a response to indicate that a page should never be cached.
If not added and the api returns a cached response, the browser also caches the data into disk cache.
Meaning we don't want caching to happen at browser level on client side as clinent will see data from
disk cache even if it is changed on server side.
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
add_never_cache_headers(response)
return response
Then add this middleware in your settings,
MIDDLEWARE_CLASSES = (
...
'your_app.middleware.DisableClientSideCachingMiddleware'
...
)
- [Django]-AssertionError: database connection isn't set to UTC
- [Django]-Django: Safely Remove Old Migrations?
- [Django]-Speeding up Django Testing