Bestrijding van cache aan de clientzijde in Django

Ik gebruik de snelkoppeling render_to_response en wil geen specifiek Response-object maken om extra headers toe te voegen om caching aan de clientzijde te voorkomen.

Ik zou graag een reactie willen hebben die het volgende bevat:

  • Pragma: geen cache
  • Cache-controle: geen cache
  • Cache-controle: moet opnieuw valideren

En alle andere handige manieren die browsers hopelijk zullen interpreteren als richtlijnen om caching te voorkomen.

Is er een no-cache middleware of iets dergelijks dat de truc kan doen met minimale code-inbraak?


Antwoord 1, autoriteit 100%

U kunt dit bereiken met behulp van de cache_control-decorator. Voorbeeld uit de documentatie:

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

Antwoord 2, autoriteit 54%

Deze aanpak (kleine wijziging van de oplossing van L. De Leo) met een aangepaste middleware heeft voor mij goed gewerkt als een oplossing voor de hele 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

Dit maakt gebruik van add_never_cache_headers.


Als u dit wilt combineren met UpdateCacheMiddlewareen FetchFromCacheMiddleware, om server-side caching in te schakelen en client-side caching uit te schakelen, moet u DisableClientSideCachingMiddlewarevoor alles, zoals dit:

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

Antwoord 3, autoriteit 16%

Als aanvulling op bestaande antwoorden. Hier is een decorateur die extra headers toevoegt om caching uit te schakelen:

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

En je kunt het gebruiken als:

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

Antwoord 4, autoriteit 8%

Eigenlijk was het schrijven van mijn eigen middleware eenvoudig genoeg:

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

Gedraagt ​​zich nog steeds niet echt zoals ik wilde, maar de @never_cache-decorateur ook niet


Antwoord 5, autoriteit 6%

Wat betreft de Google Chrome-browser (versie 34.0.1847.116 m) en de andere browsers, ontdekte ik dat alleen de @cache_control-decorator werkt. Ik gebruik Django 1.6.2.

Gebruik het als volgt:

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

Antwoord 6, autoriteit 6%

Hier is een herschrijving van @Meilo’s antwoordvoor 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

Antwoord 7, autoriteit 6%

Ik krabde mijn hoofd toen de drie magische metaniet werkten in Firefox en 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" />

Blijkbaar kan dit gebeuren omdat sommige browsers de metaaan de clientzijde negeren, dus het moet aan de serverzijde worden afgehandeld.

Ik heb alle antwoorden van dit bericht geprobeerd voor mijn klasgebaseerde weergaven (django==1.11.6). Maar verwijzend naar de antwoorden van @Lorenzo en @Zags, besloot ik een middleware te schrijven waarvan ik denk dat het een simpele is.

Dus toe te voegen aan andere goede antwoorden,

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

Other episodes