- August 5, 2011
- django generic-views class-based-views decorator
- 2 (after 2 ratings)
Converts a passed decorator to one that can be applied to a class based view (ie. automatically decorates dispatch). This means no more overriding dispatch for every view / request method you want to apply decorators to.
Works in Django 1.3 but I suspect it probably works in 1.2 as well.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
from django.utils.decorators import method_decorator def view_decorator(orig_dec): """ Convert the provided decorator to one that can be applied to a view class (ie. automatically decorates dispatch) """ # We're going to be applying a regular decorator to a method, so the first # step is to convert it to a method decorator. method_dec = method_decorator(orig_dec) # This is the decorator we're actually going to return. Since we're # returning a class decorator, it takes a single argument, the class # that it's decorating. It therefore returns this as well. def dec(cls): # We're about to change what cls.dispatch refers to, so we need to # keep a reference to the original dispatch around so that we can # call it later. orig_dispatch = cls.dispatch def _dispatch(self, *args, **kwargs): # Right - decorate the original dispatch method using our new, # method-ised version of the decorator we were passed in to start # with decorated = method_dec(orig_dispatch) # Finally, we can call the decorated dispatch() method. return decorated(self, *args, **kwargs) # Replace the original dispatch with our new dispatch function. We # kept a reference to the old dispatch method earlier, in a closure. cls.dispatch = _dispatch return cls return dec # usage from foo.bar import view_decorator from django.contrib.auth.decorators import login_required @view_decorator(login_required) class MyView(base.TemplateView): pass