I\'m trying to do cache_page with class based views (TemplateView) and i\'m not able to. I followed instructions here:
Django--URL Caching Failing for Class Based Vi
yet another good example CacheMixin from cyberdelia github
class CacheMixin(object):
cache_timeout = 60
def get_cache_timeout(self):
return self.cache_timeout
def dispatch(self, *args, **kwargs):
return cache_page(self.get_cache_timeout())(super(CacheMixin, self).dispatch)(*args, **kwargs)
usecase:
from django.views.generic.detail import DetailView
class ArticleView(CacheMixin, DetailView):
cache_timeout = 90
template_name = "article_detail.html"
queryset = Article.objects.articles()
context_object_name = "article"
You can simply decorate the class itself instead of overriding the dispatch method or using a mixin.
For example
from django.views.decorators.cache import cache_page
from django.utils.decorators import method_decorator
@method_decorator(cache_page(60 * 5), name='dispatch')
class ListView(ListView):
...
Django docs on decorating a method within a class based view.
I didn't found a good cache solution for class based views and created my own: https://gist.github.com/svetlyak40wt/11126018
It is a mixin for a class. Add it before the main base class and implement method get_cache_params like that:
def get_cache_params(self, *args, **kwargs):
return ('some-prefix-{username}'.format(
username=self.request.user.username),
3600)
Here's my variation of the CachedView()
mixin - I don't want to cache the view if the user is authenticated, because their view of pages will be unique to them (e.g. include their username, log-out link, etc).
class CacheMixin(object):
"""
Add this mixin to a view to cache it.
Disables caching for logged-in users.
"""
cache_timeout = 60 * 5 # seconds
def get_cache_timeout(self):
return self.cache_timeout
def dispatch(self, *args, **kwargs):
if hasattr(self.request, 'user') and self.request.user.is_authenticated:
# Logged-in, return the page without caching.
return super().dispatch(*args, **kwargs)
else:
# Unauthenticated user; use caching.
return cache_page(self.get_cache_timeout())(super().dispatch)(*args, **kwargs)
You can add it as a class decorator and even add multiple using a list:
@method_decorator([vary_on_cookie, cache_page(900)], name='dispatch')
class SomeClass(View):
...
Yet another answer, we found this to be simplest and is specific to template views.
class CachedTemplateView(TemplateView):
@classonlymethod
def as_view(cls, **initkwargs): #@NoSelf
return cache_page(15 * 60)(super(CachedTemplateView, cls).as_view(**initkwargs))