Ich verwende die Verknüpfung render_to_response und möchte kein bestimmtes Antwortobjekt erstellen, um zusätzliche Header hinzuzufügen, um das clientseitige Caching zu verhindern.
Ich hätte gerne eine Antwort, die enthält:
- Pragma: kein Cache
- Cache-Kontrolle: kein Cache
- Cache-Kontrolle: muss erneut validiert werden
Und all die anderen raffinierten Möglichkeiten, die Browser hoffentlich als Anweisungen interpretieren, um das Caching zu vermeiden.
Gibt es eine No-Cache-Middleware oder ähnliches, die den Trick mit minimalem Codeeinbruch ausführen kann?
response["Cache-Control"] = "no-cache, no-store, must-revalidate"
zusammen mit@never_cache
.@never_cache
Anrufeadd_never_cache_headers()
und dies wiederum ruft,patch_cache_control()
aber dies fügt nur hinzuCache-Control:max-age=0
, was anscheinend für diese Browser nicht ausreicht. Siehe stackoverflow.com/questions/49547/…patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
response['Pragma'] = 'no-cache'
@never_cache
wurde behoben, um auf allen Browsern zu funktionieren.Dieser Ansatz (geringfügige Änderung der Lösung von L. De Leo) mit einer benutzerdefinierten Middleware hat sich für mich als standortweite Lösung bewährt:
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
Dies macht Gebrauch von
add_never_cache_headers
.Wenn Sie dies mit
UpdateCacheMiddleware
und kombinieren möchtenFetchFromCacheMiddleware
, um das serverseitige Caching zu aktivieren und gleichzeitig das clientseitige Caching zu deaktivieren, müssen SieDisableClientSideCachingMiddleware
vor allem anderen Folgendes hinzufügen :MIDDLEWARE_CLASSES = ( 'custom.middleware.DisableClientSideCachingMiddleware', 'django.middleware.cache.UpdateCacheMiddleware', # ... all other middleware ... 'django.middleware.cache.FetchFromCacheMiddleware', )
quelle
add_never_cache_headers
anstelle des manuellen Einfügens von Headern.add_never_cache_headers
auch die Header "Expires" und "Last-Modified" auf die aktuelle Zeit gesetzt. Außerdem werden ETag-Header so eingestellt, dass das Caching verhindert wird, wenn USE_ETAGS in Ihren Einstellungen festgelegt ist. Siehe github.com/django/django/blob/master/django/utils/cache.pyErgänzende Antworten ergänzen. Hier ist ein Dekorateur, der zusätzliche Header hinzufügt, um das Caching zu deaktivieren:
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
Und Sie können es verwenden wie:
class SomeView(View): @method_decorator(never_ever_cache) def get(self, request): return HttpResponse('Hello')
quelle
Eigentlich war es einfach genug, meine eigene Middleware zu schreiben:
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
Benimmt sich immer noch nicht so, wie ich es wollte, aber der @ never_cache-Dekorator auch nicht
quelle
In Bezug auf den Google Chrome-Browser (Version 34.0.1847.116 m) und die anderen Browser stellte ich fest, dass nur der
@cache_control
Dekorateur funktioniert. Ich benutze Django 1.6.2.Verwenden Sie es so:
@cache_control(max_age=0, no_cache=True, no_store=True, must_revalidate=True) def view(request): ...
quelle
Hier ist eine Neufassung von @ Meilos Antwort für 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
quelle
Ich kratzte mir am Kopf, als die drei Magie
meta
in Firefox und Safari nicht funktionierte.<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" />
Anscheinend kann es passieren, dass einige Browser die Clientseite ignorieren
meta
, daher sollte dies auf der Serverseite behandelt werden.Ich habe alle Antworten aus diesem Beitrag für meine klassenbasierten Ansichten (
django==1.11.6
) ausprobiert . Aber unter Bezugnahme auf die Antworten von @Lorenzo und @Zags habe ich beschlossen, eine Middleware zu schreiben, die ich für einfach halte.Also zu anderen guten Antworten hinzufügen,
# 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', ...
quelle