2012-01-09 82 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作爲函數簽名中參數的默認值。
相關問題