Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Django class based view mixins
# -*- coding: utf-8 -*-
from django.contrib.auth.decorators import login_required
from django.utils.cache import patch_response_headers
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page, never_cache
from django.views.decorators.csrf import csrf_exempt
class NeverCacheMixin(object):
@method_decorator(never_cache)
def dispatch(self, *args, **kwargs):
return super(NeverCacheMixin, self).dispatch(*args, **kwargs)
class LoginRequiredMixin(object):
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(LoginRequiredMixin, self).dispatch(*args, **kwargs)
class CSRFExemptMixin(object):
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(CSRFExemptMixin, self).dispatch(*args, **kwargs)
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)
class CacheControlMixin(object):
cache_timeout = 60
def get_cache_timeout(self):
return self.cache_timeout
def dispatch(self, *args, **kwargs):
response = super(CacheControlMixin, self).dispatch(*args, **kwargs)
patch_response_headers(response, self.get_cache_timeout())
return response
class JitterCacheMixin(CacheControlMixin):
cache_range = [40, 80]
def get_cache_range(self):
return self.cache_range
def get_cache_timeout(self):
return random.randint(*self.get_cache_range())
# -*- coding: utf-8 -*-
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"
@estebistec
Copy link

estebistec commented Sep 15, 2013

got these mixins in a lib anywhere? :)

@pjrobertson
Copy link

pjrobertson commented Mar 17, 2014

You shouldn't override dispatch, but the class method as_view()

See the docs, which have just been written and also the just-closed issue where we discussed it.

The reason you shouldn't override dispatch is because things break if dispatch doesn't always accept a compatible set of params

@adamtwiss
Copy link

adamtwiss commented Dec 16, 2014

This is nice - but wouldn't it be better if the CacheControlMixin called cache_control() in the same way you call cache_page in CacheMixin? This enables things like setting cache_control(private=True, public=False) and other options that the cache_control header providers. The timeout is only one of many things the cache_control can set.

@nikolas
Copy link

nikolas commented Jan 30, 2015

@pjrobertson I'm still confused - there seems to be two documented ways to make a login_required mixin:

Is one of these examples incorrect?

@oscarmlage
Copy link

oscarmlage commented May 1, 2015

What's the difference between CacheMixin and CacheControlMixin?, how could I clear the generated cache?. For example, would be nice to clear the cache when you're updating the article. Thank you in advance.

@jorgecarleitao
Copy link

jorgecarleitao commented Nov 9, 2015

class CacheMixin(object):
    cache_timeout = 60

    def dispatch(self, *args, **kwargs):
        return cache_page(self.cache_timeout)(
            super(CacheMixin, self).dispatch)(*args, **kwargs)

Seems simpler. If get_cache_timeout is to allow be overwritten, maybe adding the argument request improves it usage. Nice list of mixins :)

@mangelozzi
Copy link

mangelozzi commented Aug 26, 2019

You shouldn't override dispatch, but the class method as_view()

See the docs, which have just been written and also the just-closed issue where we discussed it.

The reason you shouldn't override dispatch is because things break if dispatch doesn't always accept a compatible set of params

I followed the link, and read the documentation, but they instruct and show one to decorate the dispatch method:
https://docs.djangoproject.com/en/2.2/topics/class-based-views/intro/#decorating-the-class
Are you sure about .as_view()?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment