Skip to content

Instantly share code, notes, and snippets.

@cyberdelia
Created September 21, 2011 08:26
Show Gist options
  • Star 70 You must be signed in to star a gist
  • Fork 30 You must be signed in to fork a gist
  • Save cyberdelia/1231560 to your computer and use it in GitHub Desktop.
Save cyberdelia/1231560 to your computer and use it in GitHub Desktop.
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"
@mangelozzi
Copy link

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