Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django still caching views with @never_cache decorator

I'm using Django with Django Rest Framework and uWSGI. I have memcached set up on the server with pylibmc backend. I have Django configured for per-site cache so every view should be cached except ones that I exempt from it using the @never_cache decorator. I can't figure out why Django is still trying to cache my API views even with Django's @never_cache decorator added. I have an API that supports read write operations for a Draft model. When I make a draft update using the UpdateAPIView, then refresh the page, it is still showing the Draft data prior to the update. I've confirmed it's not browser side cache because network logs show 200 response, not 304, and if I clear memcached and refresh the page, then the updated Draft is correctly returned.

This recently happened when I upgraded Django from 1.8 to 1.10, the ~15 pip package dependencies, the OS distro and its packages (so it's hard to pinpoint exactly what caused it).

DRF Retrieve API View

from django.views.decorators.cache import never_cache

class DraftDetail(generics.RetrieveAPIView):
    queryset = Draft.objects.all()
    serializer_class = DraftSerializer
    permission_classes = (permissions.IsAuthenticated, HasReadWriteAccess)

    @never_cache
    def dispatch(self, *args, **kwargs):
        return super(DraftDetail, self).dispatch(*args, **kwargs)

I've also tried the alternate class based @method_decorator but no change:

from django.views.decorators.cache import never_cache
from django.utils.decorators import method_decorator

@method_decorator(never_cache, name='dispatch')
class DraftDetail(generics.RetrieveAPIView):
    queryset = Draft.objects.all()
    serializer_class = DraftSerializer
    permission_classes = (permissions.IsAuthenticated, HasReadWriteAccess)

settings.py

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '127.0.0.1:11211',
    }
}
PYLIBMC_MIN_COMPRESS_LEN = 250
# The cache alias to use for storage.
CACHE_MIDDLEWARE_ALIAS = 'default'
# The number of seconds each page should be cached.
CACHE_MIDDLEWARE_SECONDS = 500
CACHE_MIDDLEWARE_KEY_PREFIX = 'app'

MIDDLEWARE_CLASSES = (
    'django.middleware.cache.UpdateCacheMiddleware',
    (...),
    'django.middleware.cache.FetchFromCacheMiddleware',
)

I also have Cache-Control:max-age=0 set in my request headers.

like image 381
ravishi Avatar asked Oct 30 '22 17:10

ravishi


1 Answers

Maybe

@method_decorator(never_cache())
like image 178
Vlax Avatar answered Nov 15 '22 10:11

Vlax