On 21 October 2010 14:31, Luke Plant <l.plant...@cantab.net> wrote: > On Thu, 2010-10-21 at 01:40 +0200, Łukasz Rekucki wrote: > >> On a related note, while writing a class_decorator() I noticed that >> method_decorator() doesn't work with decorators that set attributes on >> the view (like csrf_exempt). This is because the decorator is invoked >> on a closure inside _wrapper() during method call (i.e. during method >> call, not class creation), while as_view() only sees _wrapper - which >> has no attributes. > > Good catch! The attached patch should fix it, but it feels a bit icky, > due to the double application of the decorator. Let me know if it solves > this problem for you, or if you can think of a better way to fix it.
I does fell icky. I haven't found a better way to solve this in general case, so I started thinking about a solution designed for CBV specifically. Both are a variation on what you proposed earlier: 1) Add get_decorators() class method, that as is called by as_view(), to get a list of decorators to be applied on the closure. class MyView(View): @classmethod def get_decorators(cls): return (login_required,) This can be folded to a class decorator: def decorate_class(fdec): @wraps(fdec) def _decorator(cls): original_method = cls.get_decorators @wraps(original_method) def method_replacement(cls): return (fdec,) + original_method() cls.get_decorators = method_replacement return cls return _decorator @decorate_class(login_required): class MyView(View): pass 2) decorators class property: class MyView(View): decorators = (login_required,) # in View: def as_view(cls, **initkwargs): # all the stuff now # now the hack part that follows MRO all_decorators = sum( (c.decorators for c in cls.mro() if "decorators" in c.__dict__), []) for dec in decorators: view = dec(view) return view This also can be turned into a class decorator. -- Łukasz Rekucki -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.