In Django, how can create a single cached version of a page (same for all users) that\'s only visible to authenticated users?
The pag
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_cache
def dynamic_index(request):
# do dynamic stuff
def cached_index(request):
return dynamic_index(request)
@never_cache
def 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.
I know this is a very old question, but we have a new alternative to solve this.
You can use the decorator cache_control passing private
as True
to protect your data.
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_page
def 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', {})
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_page
def 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.