databrowse and @login_required

17 views
Skip to first unread message

Jason McVetta

unread,
May 29, 2007, 3:30:42 PM5/29/07
to django...@googlegroups.com
What is the right way to require a user be authenticated when using the databrowse module?  I tried adding @login_required decorators to both functions in databrowse.views, but that did not work -- it appears databrowse does not presently use its views.py.  I also tried decorating databrowse.DatabrowseSite.root with @login_required, but it threw this exception:

Traceback (most recent call last):
File "c:\opt\Python25\Lib\site-packages\django\core\handlers\base.py" in get_response
  77. response = callback(request, *callback_args, **callback_kwargs)
File "c:\opt\Python25\lib\site-packages\django\contrib\databrowse_jm\sites.py" in root
  120. return self.index(request)
File "c:\opt\Python25\Lib\site-packages\django\contrib\auth\decorators.py" in _checklogin
  16. if test_func(request.user):

  AttributeError at /databrowse/
  'DatabrowseSite' object has no attribute 'user'

Can someone point me in the right direction? 

Malcolm Tredinnick

unread,
May 29, 2007, 9:30:54 PM5/29/07
to django...@googlegroups.com

This is because the decorator is for a view function, which has
"request" as the first argument, whereas DatabrowseSite.root() takes a
DatabrowseSite instance as its first argument.

You could possibly write a custom version of the decorator that looked
at the second argument.

Or you could subclass DatabrowseSite -- in your own code somewhere; no
need to even modify the source -- and override the root() method to do
an auth-check first and then call DatabrowseSite.root(). Then you
replace databrowse.sites with an instance of your subclass.

Python is really cool like this: since everything's a first-class
object, you can happily import databrowse.main and then just set
databrowse.main.site to whatever you want.

That is all completely untested of course (in the sense that I haven't
actually written the code), but it should be possibly with a bit of
attention to detail and error messages.

Regards,
Malcolm

Jason McVetta

unread,
May 30, 2007, 10:58:41 AM5/30/07
to django...@googlegroups.com
On 5/29/07, Malcolm Tredinnick <mal...@pointy-stick.com> wrote:
Or you could subclass DatabrowseSite -- in your own code somewhere; no
need to even modify the source -- and override the root() method to do
an auth-check first and then call DatabrowseSite.root(). Then you
replace databrowse.sites with an instance of your subclass.


Didn't even need to subclass it.  Instead, I took what seemed the least-invasive route, and made my urls.py look like this:

from django.conf.urls.defaults import *
from django.http import HttpResponseRedirect

from django.contrib import databrowse

def authorized_databrowse(request, url):
    if request.user.is_authenticated():
        return databrowse.site.root(request, url)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)

urlpatterns = patterns('',
    (r'^databrowse/(.*)', authorized_databrowse),
    (r'^login/$', 'django.contrib.auth.views.login'),
    ...
)

Malcolm Tredinnick

unread,
May 30, 2007, 10:31:48 PM5/30/07
to django...@googlegroups.com

Looks very sensible and clean. Nice solution. :-)

Cheers,
Malcolm

>

Reply all
Reply to author
Forward
0 new messages