Как применить декоратор сделать диспетчерский метод в представлениях на основе классов Django
Читая книгу "ProDjango", я обнаружил интересный момент о применении собственного декоратора к методам в представлениях на основе классов.
Автор говорит, что мы можем вручную назначить декоратор каждому методу класса, т.е. get
, post
и так далее, или мы можем добавить наш декоратор dispatch()
метод, и если мы сделаем это, то декоратор будет применен к каждому методу класса (get
, post
так далее)
Вопрос:
Как на самом деле я могу применить декоратор для метода dispatch() представления на основе классов?
1 ответ
Вы можете использовать декоратор method_decorator
как показано здесь в документах.
Из документов:
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)
Или вы можете сделать это в вашем 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())),
)
Обновить:
Начиная с Django 1.9, теперь вы можете использовать декоратор метода на уровне класса. Вам нужно будет передать название метода, который будет оформлен. Поэтому нет необходимости отменять диспетчеризацию только для того, чтобы применить декоратор.
Пример:
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
Кроме того, вы можете определить список или кортеж декораторов и использовать их вместо вызова method_decorator()
многократно.
Пример (два класса ниже одинаковы):
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'