Luchando en el caché del lado del cliente en Django

Estoy usando el acceso directo render_to_response y no quiero crear un objeto Response específico para agregar encabezados adicionales para evitar el almacenamiento en caché del lado del cliente.

Me gustaría tener una respuesta que contenga:

  • Pragma: no-caché
  • Cache-control: no-caché
  • Control de caché: debe revalidar

Y todas las otras formas ingeniosas que los navegadores interpretarán como directivas para evitar el almacenamiento en caché.

¿Hay un middleware sin caché o algo similar que pueda hacer el truco con una mínima intrusión de código?

Puede lograr esto usando el decorador cache_control. Ejemplo de la documentación :

from django.views.decorators.cache import never_cache @never_cache def myview(request): # ... 

Este enfoque (una ligera modificación de la solución de L. De Leo) con un middleware personalizado me ha funcionado como una solución para todo el sitio:

 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 

Esto hace uso de add_never_cache_headers .


Si desea combinar esto con UpdateCacheMiddleware y FetchFromCacheMiddleware , para habilitar el almacenamiento en caché del lado del servidor mientras se desactiva el almacenamiento en memoria caché del lado del cliente, debe agregar DisableClientSideCachingMiddleware antes que cualquier otro, como este:

 MIDDLEWARE_CLASSES = ( 'custom.middleware.DisableClientSideCachingMiddleware', 'django.middleware.cache.UpdateCacheMiddleware', # ... all other middleware ... 'django.middleware.cache.FetchFromCacheMiddleware', ) 

Para complementar las respuestas existentes. Aquí hay un decorador que agrega encabezados adicionales para deshabilitar el almacenamiento en caché:

 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 

Y puedes usarlo como:

 class SomeView(View): @method_decorator(never_ever_cache) def get(self, request): return HttpResponse('Hello') 

En realidad, escribir mi propio middleware fue bastante fácil:

 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 

Todavía no se comporta como yo quería, pero tampoco el decorador @never_cache

En cuanto al navegador Google Chrome (Versión 34.0.1847.116 m) y los otros navegadores, encontré que solo el decorador @cache_control está funcionando. Yo uso Django 1.6.2.

Úselo así:

 @cache_control(max_age=0, no_cache=True, no_store=True, must_revalidate=True) def view(request): ... 

Aquí hay una reescritura de la respuesta de @Meilo para 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 

Me estaba rascando la cabeza cuando los tres meta mágicos no funcionaban en Firefox y Safari.

    

Aparentemente, puede suceder porque algunos navegadores ignoran el meta lado del cliente, por lo que debe manejarse en el lado del servidor.

django==1.11.6 todas las respuestas de esta publicación para mis vistas basadas en clase ( django==1.11.6 ). Pero refiriéndome a las respuestas de @Lorenzo y @Zags, decidí escribir un middleware que creo que es simple.

Entonces, agregando otras buenas respuestas,

 # 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', ...