2012-01-09 85 views
7

我是新来的StackOverflow和Django的扭转auth.views.login ...Django的新手:尝试在login_required()装饰

简要的问题(参见下面的“长期问题”),下面的代码在安装MyApps/views.py失败:

from django.core.urlresolvers import reverse 
... 
@login_required(login_url=reverse('django.contrib.auth.views.login')) 
def my_view(request): 
    pass 

错误是:

ViewDoesNotExist at/
tried my-view2 in module myproject.myapps.views. Error was: 'module' object has no attribute 'my-view2' 

'我的-视图2' 在安装MyApps/views.py定义我的视图之后(且在myproject的被引用/ urls.py)

我想这里有鸡和鸡蛋这样的东西,但我无法弄清楚我错在哪里。 我尝试建立LOGIN_URL settings.py中一样具有相同的错误:

from django.core.urlresolvers import reverse 
... 
LOGIN_URL=reverse('django.contrib.auth.views.login') 

现在长的问题(什么情况下,我为什么要这么做):

Django的1.3.1我的工作得到了以下观点,与auth.decorator保护:

@login_required 
def my_view(request) 
    pass 

这个装饰默认重定向到/帐号/登录(它工作和对我很好)。

使用DEVELOPPEMENT服务器整个URL是相对于本地主机:/

在生产服务器(使用WSGI),整个URL相对于我的服务器:/ PATH1/ 这是由于apache的构造比如说: WSGIScriptAlias/path1 /var/www/path/to/script.wsgi

这对我来说很好。

在myproject/urls.py中定义的所有URL都是自动相对于这个新路径,所以感谢django,我的所有网站都在处理这个新的“html根目录”。

但我的受保护视图仍然重定向到我的服务器:/帐号/登录/代替邻我的服务器:/路径1 /帐号/密码

到目前为止,我让它工作使用settings.py

LOGIN_URL=/path1/accounts/login/ 

或使用LOGIN_URL参数的“login_required”装饰:在这两个阿帕奇

@login_required(login_url="/path1/accounts/login/") 

不过,我想,这个登录视图相对于整个网站的路径,而无需配置“路径1”和django/settings.py

我不觉得在settings.py中使用reverse是正确的做 也不是在视图装饰器中使用它。但到目前为止,我不知道如何处理...

+0

你可以发布你的urls.py吗? – 2012-01-09 15:18:00

+0

你真的有一个定义为'my-view2'的视图吗?这不是一个有效的Python名称,''是一个运算符。如果你这样做,你应该把它重命名为'my_view2'。 – brutasse 2012-01-09 16:15:23

回答

13

您不能在login_required修饰符中或在settings.py中使用reverse,因为在设置/视图时URL配置尚未加载进口。

在Django 1.4+中,您可以使用reverse_lazy。在Django的早期版本中,您可以回溯reverse_lazy,或查看我对问题reverse url mapping in settings的回答。

在Django 1.5+中,LOGIN_URL设置接受指定的url模式。例如,如果你的名字你登录URL模式“登陆”,那么你可以简单地做:

LOGIN_URL = 'login' 
+0

感谢您的准确答案!你给的选项很有趣。在1.3.1版中知道这是不可能的,我会节省一些时间,试图使其工作! – rhn 2012-01-09 16:59:46

+0

以下是早期版本的一个片段:http://djangosnippets.org/snippets/499/ – 2012-02-01 00:55:25

+0

谢谢。我遇到了这个问题,使我自己的装饰器,并不得不确保它太早强制评估'reverse_lazy(...)'。 – cloudrave 2014-06-13 05:41:45

0

以下反向()函数,我发现另一种方式来实现我的目标:

我确定使用标准的网址(帐户/登录等) 我只是想预先在我的情况下不是“/”的HTML文档根目录。

从我的测试,这并不在settings.py在我views.py工作(这是在这一步太早?)

@login_required(login_url="/path1/accounts/login/") 

成为

from django.core.urlresolvers import get_script_prefix 
@login_required(login_url=get_script_prefix() + "accounts/login/") 
+1

您对URL进行了硬编码,这违反了DRY! – 2013-01-04 17:38:50

0

使用reverse_lazy()

documents说:

当您在加载项目的URLConf之前需要使用URL反转时,它非常有用。一些常见的情况下,这个功能是必要的是:

  • 提供一个反向的URL作为一个基于类的基础视图的url属性。
  • 向装饰器(例如django.contrib.auth.decorators.permission_required()装饰器的login_url参数)提供反向URL。
  • 提供反向URL作为函数签名中参数的默认值。
相关问题