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.