Class-based views & authentication

693 views
Skip to first unread message

Pascal Germroth

unread,
Feb 8, 2011, 10:34:28 AM2/8/11
to django...@googlegroups.com
Hi,

I'm new to Django, but since this project will take a while I'm already
using 1.3 alpha since it will probably be released when I'm done…

As I understand it, the preferred method now are class-based views. But
I seem to be missing some kind of AuthenticationMixin… right now, have
to override `dispatch`, add the authentication decorator as one would
for function views, and call super.

To make things a bit easier, I'm about to write my own mixin for that so
I only have to provide a method that checks if credentials are OK.


Or am I doing this completely wrong?

--
Pascal Germroth

Russell Keith-Magee

unread,
Feb 8, 2011, 7:16:25 PM2/8/11
to django...@googlegroups.com

You're not doing anything wrong -- you've hit one of the slightly
sharp corners of class-based generic views.

You can still use a decorator -- but at the point of deploying a view.

login_required(MyView.as_view())

You can't decorate the MyView class itself -- Django doesn't provide
the tools to turn a view decorator into a class decorator.

As you've noticed, you can override the dispatch to decorate the view
as required, and if you have a common authentication pattern, you can
put that logic into a mixin.

In a general sense, the problem that Django has as a project is that
while login_required is a very common decorator for checking
authentication, it isn't the *only* decorator that can be used.

Authentication -- and decorating views in general -- is a fairly
common patterns, though, so we obviously need to do something to
address this. There have been a couple of discussions about the best
way to implement that feature. However, these discussions are a work
in progress. In the interim, a mixin is probably the best approach.

Yours,
Russ Magee %-)

Pascal Germroth

unread,
Feb 9, 2011, 1:06:33 PM2/9/11
to django...@googlegroups.com
Hi,

>> To make things a bit easier, I'm about to write my own mixin for that so
>> I only have to provide a method that checks if credentials are OK.
>

> As you've noticed, you can override the dispatch to decorate the view
> as required, and if you have a common authentication pattern, you can
> put that logic into a mixin.


For future reference, this is what I use now:


class LoginMixin(object):
def get_test_func(self):
return getattr(self, 'test_func', lambda u: u.is_authenticated())
def get_login_url(self):
return getattr(self, 'login_url', None)
def get_redirect_field_name(self):
return getattr(self, 'redirect_field_name', None)
def dispatch(self, request, *args, **kwargs):
from django.contrib.auth.decorators import user_passes_test
return user_passes_test(
self.get_test_func(),
login_url = self.get_login_url(),
redirect_field_name = self.get_redirect_field_name()
)(super(LoginMixin, self).dispatch
)(request, *args, **kwargs)


class DashboardView(LoginMixin, TemplateView):
login_url = '/base/login'
template_name = 'dashboard.html'

LoginMixin *must* be the first base class, otherwise it could not
override View.dispatch in the other base classes.


--
Pascal Germroth

Andre Terra

unread,
Feb 16, 2011, 1:41:31 PM2/16/11
to django...@googlegroups.com, Pascal Germroth
Thank you for sharing that, Pascal. I'm already using it on my project!

I've modified get_login_url to fallback to settings.LOGIN_URL, though.

I'll keep an eye open on the development of this, as CBVs really are great to work with.


Sincerely,
Andre Terra



--
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.


Andre Terra

unread,
Feb 16, 2011, 1:46:13 PM2/16/11
to django...@googlegroups.com, Pascal Germroth
I should also add that the functionality described in the docs simply did not work for me: http://docs.djangoproject.com/en/dev//topics/class-based-views/#decorating-the-class

My attempt to follow that approach is registered here: http://dpaste.com/hold/423359/


Sincerely,
Andre Terra

Łukasz Rekucki

unread,
Feb 16, 2011, 3:59:28 PM2/16/11
to django...@googlegroups.com
On 16 February 2011 19:46, Andre Terra <andre...@gmail.com> wrote:
> I should also add that the functionality described in the docs simply did
> not work for me:
> http://docs.djangoproject.com/en/dev//topics/class-based-views/#decorating-the-class
>
> My attempt to follow that approach is registered here:
> http://dpaste.com/hold/423359/

It's an error in the docs. It should be:

class ProtectedView(TemplateView):
template_name = 'secret.html'

@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(ProtectedView, self).dispatch(*args, **kwargs)

You can report it to the bug tracker here:
http://code.djangoproject.com/newticket

Thanks.

--
Łukasz Rekucki

Andre Terra

unread,
Feb 17, 2011, 6:55:34 AM2/17/11
to django...@googlegroups.com, Łukasz Rekucki
Reported!

http://code.djangoproject.com/ticket/15328


Sincerely,
André Terra

2011/2/16 Łukasz Rekucki <lrek...@gmail.com>

--
Reply all
Reply to author
Forward
0 new messages