J'utilise le raccourci render_to_response et je ne veux pas créer un objet Response spécifique pour ajouter des en-têtes supplémentaires pour empêcher la mise en cache côté client.
J'aimerais avoir une réponse qui contient:
Et toutes les autres façons astucieuses que les navigateurs interpréteront, espérons-le, comme des directives pour éviter la mise en cache.
Existe-t-il un middleware sans cache ou quelque chose de similaire qui peut faire l'affaire avec une intrusion de code minimale?
Vous pouvez y parvenir en utilisant le décorateur cache_control. Exemple de la documentation :
from Django.views.decorators.cache import never_cache
@never_cache
def myview(request):
# ...
Cette approche (légère modification de la solution de L. De Leo) avec un middleware personnalisé a bien fonctionné pour moi en tant que solution à l'échelle du site:
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
Cela utilise add_never_cache_headers
.
Si vous souhaitez combiner cela avec UpdateCacheMiddleware
et FetchFromCacheMiddleware
, pour activer la mise en cache côté serveur tout en désactivant la mise en cache côté client, vous devez ajouter DisableClientSideCachingMiddleware
avant tout le reste, comme ceci :
MIDDLEWARE_CLASSES = (
'custom.middleware.DisableClientSideCachingMiddleware',
'Django.middleware.cache.UpdateCacheMiddleware',
# ... all other middleware ...
'Django.middleware.cache.FetchFromCacheMiddleware',
)
Pour compléter les réponses existantes. Voici un décorateur qui ajoute des en-têtes supplémentaires pour désactiver la mise en cache:
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
Et vous pouvez l'utiliser comme:
class SomeView(View):
@method_decorator(never_ever_cache)
def get(self, request):
return HttpResponse('Hello')
En fait, écrire mon propre middleware était assez simple:
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
Ne se comporte toujours pas vraiment comme je le voulais, mais le décorateur @never_cache non plus
En ce qui concerne le navigateur Google Chrome (version 34.0.1847.116 m) et les autres navigateurs, j'ai constaté que seul le @cache_control
le décorateur travaille. J'utilise Django 1.6.2.
Utilisez-le comme ceci:
@cache_control(max_age=0, no_cache=True, no_store=True, must_revalidate=True)
def view(request):
...
Voici une réécriture de @ 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
Je me grattais la tête lorsque les trois magie meta
ne fonctionnaient pas dans Firefox et 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" />
Apparemment, cela peut se produire car certains navigateurs ignoreront le côté client meta
, il doit donc être géré côté serveur.
J'ai essayé toutes les réponses de ce post pour mes vues basées sur la classe (Django==1.11.6
). Mais en me référant aux réponses de @Lorenzo et @Zags, j'ai décidé d'écrire un middleware qui je pense est simple.
Donc, en ajoutant d'autres bonnes réponses,
# 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',
...