1) decorate the final view (for use in urls.py):
decorated_view = login_required(MyView.as_view)
In this option, you lose the ability to subclass the decorated view.
2) decorate the dispatch method. You need to turn login_required into
a method decorator first (Django should probably provide a tool for
this). Here[1] is an example how to do this.
class MyDecoratedView(MyView):
@on_method(login_required):
def dispatch(self, *args, **kwargs):
# do any extra stuff here
return super(MyDecoratedView, self).dispatch(*args, **kwargs)
3) Make a class decorator, that does the above, so you could do:
@on_dispatch(login_required)
class MyDecoratedView(MyView):
pass
>
> I was going to write something like LoginRequiredMixin, but I have no
> idea how to do this. I need to run my code before .dispatch(), but I
> also have to call the old dispatch, but since Mixin aren't inherited
> from View, I can't just override method and use super().
This is option #4. You can just do:
class LoginRequiredMixin(object):
def dispatch(self, *args, **kwargs):
bound_dispatch = super(LoginRequired, self).dispatch
return login_required(bound_dispatch)(*args, **kwargs)
[1]: http://www.toddreed.name/content/django-view-class/
--
Łukasz Rekucki
Does python's super really works the way like in the last option?
--
Best Regards,
Valentin Golev
Lead Developer
r00, http://r00.ru
http://valyagolev.net
+7 921 789 0895, avaiable 12:00-18:00 MSK
2010/10/19 Łukasz Rekucki <lrek...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups "Django users" group.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to django-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>
>
class MyView(LoginRequiredMixin, TemplateView):
pass
It should work as expected.
--
Łukasz Rekucki
Django does :-) It's called method_decorator.
from django.utils.decorators import method_decorator
class MyDecoratedView(MyView):
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
#...
This works for any method on any class, that you want to decorate with
any function-based decorator.
As a point of interest, the django.utils.decorators module has a
couple of other useful utilities in this vein, such as
decorator_from_middleware (which, predictably, enables you to turn any
middleware into a decorator that wraps a single view).
Yours,
Russ Magee %-)
This discussion has moved to django-developers. It starts in [1] and
then continued in [2]. There is also a ticket #14512 for tracking this
issue[3]. All help is welcome :)
>
> This solution looks cleanest, and is easiest to implement. However
> there is
> a problem if two or more similar mixins are used: The order of the
> calls are
> dependant on the order the view inherits the mixins.
Yes it is. But I don't really see a problem with this. That's how
Python works. Wrapping the mixin construction to a class decorator
should make this a bit more obvious in what order the decorators will
be applied. With the code above, to wrap your view "MyView" with
a login_required you would need to do something like this:
class MyProtectedView(LoginRequiredMixin, MyView):
pass
> If you make a misstake
> in the inheritance-order, your mixin might not be called at all, which
> might not always be whats intended.
If all classes you inherit from play nicely (that means they call
super() in dispatch()), they your mixin will always be called. It
might be
called *earlier* then you expect, but not later or not at all.
>
> I am personally working on option #3, with a simple linked list of
> callables
> that calls each other until the original "get", "post", etc. is
> called.
See the links. There are some problems with decorators that leave
attributes (like csrf_protect) to consider. I will be more than happy
to work toghether.
[1]: http://groups.google.com/group/django-developers/browse_frm/thread/f4bad32127776177
[2]: http://groups.google.com/group/django-developers/browse_frm/thread/f36447f96277fe8c
[3]: http://code.djangoproject.com/ticket/14512
--
Łukasz Rekucki