On Thursday 13 May 2010 01:14:35 fitzgen wrote: > * How to decorate the __call__ method without doing a pointless > override of __call__ that just calls super so that you have > something to @decorate on top of. Check out the meta class on line > 175. This allows you to specify 'decorators = [login_required, > permission_required("polls.can_vote")]' on your subclass. I showed > this to Jacob at DjangoSki, and he seemed positive.
I personally don't like metaclasses if we can find another way. Here are some alternatives which use Plain Old Python: 1) from Python 2.6 we could use class decorators, and we could use the 'old style' MyClass = some_class_decorator(MyClass) until we move to Python 2.6. 2) class Foo(View): __call__ = some_decorator(View.__call__) 3) Add the decorators when you call 'instantiator' (which, by the way, I would rather call 'make_view' or something more specific). You would then have, *in views.py*: 3a) my_view = some_decorator(make_view(MyViewClass)) or possibly (though I don't think this adds much): 3b) my_view = make_view(MyViewClass, decorators=[some_decorator]) This has some significant advantages: - you don't need to worry about method decorators - you can re-use MyViewClass with different decorators - it protects us from changing the URLconf. The URLconf always has a reference to the 'my_view' function, rather than MyViewClass. Class-based views then remain an implementation detail, just as they ought to be. It may well be that a re-usable app provides some views and might switch from class-based views to normal functions, and URLconfs should be insulated from that change. I don't like the idea of special-casing class based views anywhere, whether to cope with state or anything else. I think a view should still be 'a callable that takes a request and returns a response'. If that means we have to add an extra line to create a view function from a view class, so be it. Given that it is going to be possible to use any/all of these whatever Django provides, I think I'm quite strongly in favour of 3a), and opposed to adding a metaclass which really doesn't add anything significant. Metaclasses add complications for people attempting to understand code, and should be used only when you really need them. > * How to decorate methods, when the decorator expects the first > argument to be request, and not self. See line 8. Ideally though, > Django's decorators would handle this, rather than forcing the use > of decorate_method_with on to the end users. We already have 'django.utils.decorators.method_decorator' to cope with this. All attempts to have decorators that automatically adapt to functions/methods have failed. See my message here http://groups.google.com/group/django-developers/msg/f36976f5cfbcbeb3 It has some attachments with test cases that show how our previous attempt to do this didn't work in some situations. One thing we could do to make it nicer for the end user is to create our own 'method' versions of all supplied decorators i.e: cache_page_m = method_decorator(cache_page) for every decorator we provide, so that people don't need to do that themselves. However, this point may be moot given the discussion above. Luke -- "Mistakes: It could be that the purpose of your life is only to serve as a warning to others." (despair.com) Luke Plant || http://lukeplant.me.uk/ -- 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.