--
Ticket URL: <https://code.djangoproject.com/ticket/16626>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* needs_better_patch: => 0
* resolution: => worksforme
* needs_tests: => 0
* needs_docs: => 0
Comment:
I'm not in favor of tying the generic views to the auth framework. If we
add a special case for `login_required`, the next question is obviously
going to be about `permission_required('foo.bar')`. Clearly, it isn't
desireable to duplicate the auth API in the generic views.
What about defining your view like this:
{{{
class MyView(...):
# this is a generic view
...
my_view = login_required(MyView.as_view())
}}}
and using `my_view` in your URLconf?
If you have many generic views that should be decorated with login
required, an alternative is to implement a mixin, like this:
{{{
class LoginRequiredMixin(object):
def as_view(cls):
return login_required(super(LoginRequiredMixin, cls).as_view())
class MyView(LoginRequiredMixin, ...):
# this is a generic view
...
}}}
and use `MyView.as_view()` is your URLconf.
--
Ticket URL: <https://code.djangoproject.com/ticket/16626#comment:1>
Comment (by xhannan):
I have been trying to implement the LoginRequiredMixin class the way it is
shown above, but running into some issues. Here is the error message I
get --
"unbound method as_view() must be called with HomeView instance as first
argument (got nothing instead)"
I have implemented (rather copied and pasted) the LoginRequiredMixin
class. Here is the code --
{{{
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
class LoginRequiredMixin(object):
def as_view(cls):
return login_required(super(LoginRequiredMixin, cls).as_view())
class HomeView(LoginRequiredMixin, TemplateView):
template_name = 'web/home.html'
}}}
Here is my urls.py file --
{{{
from django.conf.urls import patterns, url
from web.views import *
urlpatterns = patterns('web',
url(r'^$', HomeView.as_view(), name='web-home'),
url(r'^login/$', LoginView.as_view(), name='web-
login'),
)
}}}
Here is the complete error message on browser --
{{{
TypeError at /web/
unbound method as_view() must be called with HomeView instance as first
argument (got nothing instead)
Request Method: GET
Request URL: http://127.0.0.1:8000/web/
Django Version: 1.5.1
Exception Type: TypeError
Exception Value:
unbound method as_view() must be called with HomeView instance as first
argument (got nothing instead)
Exception Location: /Users/khan/PycharmProjects/DjangoTest/web/urls.py
in <module>, line 5
Python Executable: /Users/khan/virtuanenvs/django-test-env/bin/python
Python Version: 2.7.4
Python Path:
['/Users/khan/PycharmProjects/DjangoTest',
'/Applications/PyCharm.app/helpers/pydev',
'/Users/khan/PycharmProjects/DjangoTest',
'/Users/khan/virtuanenvs/django-test-env/lib/python27.zip',
'/Users/khan/virtuanenvs/django-test-env/lib/python2.7',
'/Users/khan/virtuanenvs/django-test-env/lib/python2.7/plat-darwin',
'/Users/khan/virtuanenvs/django-test-env/lib/python2.7/plat-mac',
'/Users/khan/virtuanenvs/django-test-env/lib/python2.7/plat-mac/lib-
scriptpackages',
'/Users/khan/virtuanenvs/django-test-env/lib/python2.7/lib-tk',
'/Users/khan/virtuanenvs/django-test-env/lib/python2.7/lib-old',
'/Users/khan/virtuanenvs/django-test-env/lib/python2.7/lib-dynload',
'/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
'/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-
darwin',
'/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
'/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-
mac',
'/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac
/lib-scriptpackages',
'/Users/khan/virtuanenvs/django-test-env/lib/python2.7/site-packages',
'/Users/khan/virtuanenvs/django-test-env/lib/python2.7/site-
packages/setuptools-0.6c11-py2.7.egg-info']
Server time: Mon, 22 Apr 2013 04:55:05 -0400
}}}
What did I miss? Please help! Thanks a bunch.
--
Ticket URL: <https://code.djangoproject.com/ticket/16626#comment:2>
Comment (by jarus):
With the `@classmethod` decorader the code example works fine.
{{{
from django.contrib.auth.decorators import login_required
class LoginRequiredMixin(object):
@classmethod
def as_view(cls):
return login_required(super(LoginRequiredMixin, cls).as_view())
}}}
I aggree with aaugustin that a mixin is the better solution instead a
attribute in the generic view but maybe it is possible to put this mixin
in `django.contrib.auth`.
--
Ticket URL: <https://code.djangoproject.com/ticket/16626#comment:3>
Comment (by StephenChan):
For anyone else stumbling upon this ticket years later, three mixins
including `LoginRequiredMixin` were added by #24914 and made available in
Django 1.9. Docs
[https://docs.djangoproject.com/en/dev/topics/auth/default/#the-
loginrequired-mixin here].
--
Ticket URL: <https://code.djangoproject.com/ticket/16626#comment:4>