Reading a 'ProDjango' book, I've found interesting moment about applying custom decorator to methods in class-based views.
Author says that we can either manually assign decorator to each method of class, i.e., get
, post
and so on, or we can add our decorator to dispatch()
method and if we do so then decorator will be applied to each method of class(get
, post
etc)
Question is:
How actually I can apply decorator to dispatch() method of Class-based view?
You can use the decorator method_decorator
as shown here in the docs.
From the docs:
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
class ProtectedView(TemplateView):
template_name = 'secret.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(ProtectedView, self).dispatch(*args, **kwargs)
Or you can do it in your urls.py:
from django.conf.urls import patterns
from django.contrib.auth.decorators import login_required
from myapp.views import MyView
urlpatterns = patterns('',
(r'^about/', login_required(MyView.as_view())),
)
Update:
As of Django 1.9, you can now use the method decorator at the class level. You will need to pass the name of the method to be decorated. So there's no need to override dispatch just to apply the decorator.
Example:
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
Moreover, you can define a list or tuple of decorators and use this instead of invoking method_decorator()
multiple times.
Example(the two classes below are the same):
decorators = [never_cache, login_required]
@method_decorator(decorators, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
@method_decorator(never_cache, name='dispatch')
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'