Greg
Greg

Reputation: 47164

Django - Disable Page Level Caching by User

I've set up page level caching for many of our pages. However once in a while an admin user logs in to preview potential changes to the site.

Is there a way to disable page level caching just for these users?

I read through the docs but I didn't see anything.

Update: Here's my attempt based on v1k45's answer:

from django.middleware.cache import FetchFromCacheMiddleware


logger = logging.getLogger(__name__)


class ExceptImpersonateFetchFromCacheMiddleware(FetchFromCacheMiddleware):
    def process_request(self, request):
        # Break out of caching is we're using impersonate
        if request.user and hasattr(request.user, 'is_impersonate') and request.user.is_impersonate:
            logger.warning("Skipping cache_page for user %s because it is impersonation" % str(request.user))
            request._cache_update_cache = False
            return None
        # Normal flow:
        return super(ExceptImpersonateFetchFromCacheMiddleware, self).process_request(request)

Upvotes: 0

Views: 344

Answers (1)

v1k45
v1k45

Reputation: 8250

You can extend the CacheMiddleware provided by django such that the admin users always see fresh content instead of cached.

Have a look at the source code for FetchFromCacheMiddleware, you can see this code snippet:

def process_request(self, request):
    [...]
    if request.method not in ('GET', 'HEAD'):
        request._cache_update_cache = False
        return None  # Don't bother checking the cache.

The if condition here tells django to skip cache and don't update the existing cached data if the request method is not GET or HEAD.

Similarly, you can add a check where you skip the cache if the user is an admin. Roughly it will look like this:

def process_request(self, request):
    [...snip..]
    if request.user.is_staff:
        request._cache_update_cache = False
        return None  # Don't bother checking the cache.

UPDATE: The cache_page decorator uses django's CacheMiddleware which extends the functionality of FetchFromCacheMiddleware and UpdateCacheMiddleware.

Now you'll have to make your own version of CacheMiddleware and cache_page decorator. This custom_cache_page decorator will call your CustomCacheMiddleware which extends your CustomFetchFromCacheMiddleware and django's UpdateCacheMiddleware.

After you have completed the CustomCacheMiddleware, you'll have to replace django's CacheMiddleware with your own. This can be done by changing MIDDLEWARE_CLASSES tuple in settings.py.

Upvotes: 1

Related Questions