@@ -537,3 +537,60 @@ Because of the way that Python resolves method overloading, the local
537537:func:`render_to_response()` implementation will override the
538538versions provided by :class:`JSONResponseMixin` and
539539:class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`.
540+
541+ Decorating class-based views
542+ ============================
543+
544+ .. highlightlang:: python
545+
546+ The extension of class-based views isn't limited to using mixins. You
547+ can use also use decorators.
548+
549+ Decorating in URLconf
550+ ---------------------
551+
552+ The simplest way of decorating class-based views is to decorate the
553+ result of the :meth:`~django.views.generic.base.View.as_view` method.
554+ The easiest place to do this is in the URLconf where you deploy your
555+ view::
556+
557+ from django.contrib.auth.decorators import login_required
558+ from django.views.generic import TemplateView
559+
560+ urlpatterns = patterns('',
561+ (r'^about/',login_required(TemplateView.as_view(template_name="secret.html"))),
562+ )
563+
564+ This approach applies the decorator on a per-instance basis. If you
565+ want every instance of a view to be decorated, you need to take a
566+ different approach.
567+
568+ Decorating the class
569+ --------------------
570+
571+ To decorate every instance of a class-based view, you need to decorate
572+ the class definition itself. To do this you apply the decorator to one
573+ of the view-like methods on the class; that is,
574+ :meth:`~django.views.generic.base.View.dispatch`, or one of the HTTP
575+ methods (:meth:`~django.views.generic.base.View.get`,
576+ :meth:`~django.views.generic.base.View.post` etc).
577+
578+ A method on a class isn't quite the same as a standalone function, so
579+ you can't just apply a function decorator to the method -- you need to
580+ transform it into a method decorator first. The ``method_decorator``
581+ decorator transforms a function decorator into a method decorator so
582+ that it can be used on an instance method.
583+
584+ from django.contrib.auth.decorators import login_required
585+ from django.utils.decorators import method_decorator
586+ from django.views.generic import TemplateView
587+
588+ class ProtectedView(TemplateView):
589+ template_name = 'secret.html'
590+
591+ @method_decorator(login_required)
592+ def dispatch(self, **kwargs):
593+ return super(ProtectedView, self).dispatch(**kwargs)
594+
595+ In this example, every instance of :class:`ProtectedView` will have
596+ login protection.
0 commit comments