Django Caching for Authenticated Users Only Django Caching for Authenticated Users Only django django

Django Caching for Authenticated Users Only


The default cache_page decorator accepts a variable called key_prefix. However, it can be passed as a string parameter only. So you can write your own decorator, that will dynamically modify this prefix_key based on the is_authenticated value. Here is an example:

from django.views.decorators.cache import cache_pagedef cache_on_auth(timeout):    def decorator(view_func):        @wraps(view_func, assigned=available_attrs(view_func))        def _wrapped_view(request, *args, **kwargs):            return cache_page(timeout, key_prefix="_auth_%s_" % request.user.is_authenticated())(view_func)(request, *args, **kwargs)        return _wrapped_view    return decorator

and then use it on the view:

@cache_on_auth(60*60)def myview(request)

Then, the generated cache_key will look like:

cache key:   views.decorators.cache.cache_page._auth_False_.GET.123456.123456

if the user is authenticated, and

cache key:   views.decorators.cache.cache_page._auth_True_.GET.789012.789012

if the user is not authenticated.


If the @wrap decorator in the @Tisho answer makes your brain hurt, or if an explicit solution is better than an implicit one, here's a simple procedural way to serve different cache results:

from django.views.decorators.cache import cache_pagedef index(request):    """    :type request: HttpRequest    """    is_authenticated = request.user.is_authenticated()    if is_authenticated:        return render_user(request)    else:        return render_visitor(request)@cache_page(5, key_prefix='user_cache')def render_user(request):    print 'refreshing user_cache'    return render(request, 'home-user.html', {})@cache_page(10, key_prefix='visitor_cache')def render_visitor(request):    print 'refreshing visitor_cache'    return render(request, 'home-visitor.html', {})


I'd advice against using the cache middleware if you want fine tuning of your caching abilities.

However, if you do want to persist keeping it, you could try something like (not saying it would work as is, but something similar to it):

@never_cachedef dynamic_index(request):    # do dynamic stuffdef cached_index(request):    return dynamic_index(request)@never_cachedef index(request):        if request.user.is_authenticaded():        return cached_index(request)    return dynamic_index(request)    

Worst case scenario, you can use cache.set('view_name', template_rendering_result), and cache.get, to just cache the HTML manually.