2012-06-08 59 views
17

我喜歡django的@login_required修飾器,但有一件事我不知道如何去做。在django的login_required修飾器中抑制「?next = blah」行爲

如果未經身份驗證的用戶嘗試訪問@login_required頁面(例如「/ private-stuff /」),我想將他們踢回主頁(例如「/ home /」)。但我不想追加一個「?next =」參數給url。換句話說,我只是想重定向到「/ home /」,而不是「/ home /?next =/private-stuff /」。

我該怎麼做?有沒有比寫我自己的裝飾者更好的方法?

回答

6

那麼,我可以想到兩種方法。首先,這將是「正確」的方式,因爲您不會破壞任何功能,只會增加新功能:創建您自己的login_required修飾器。但問題是,Django 確實將登錄功能後的重定向捲起,它需要大量的零件。 login_required decorator實際上只是user_passes_test decorator的一個包裝,它依次調用redirect_to_login view,它的視圖將next參數添加到查詢字符串中。在您的自定義裝飾器中,您可以將所有或部分功能直接放入裝飾器中,但您需要參考所有三個代碼。

另外,和更簡單的選擇,是創造一些中間件去除查詢字符串,如果它被設置:

from django.conf import settings 
from django.http import HttpResponseRedirect 

class RemoveNextMiddleware(object): 
    def process_request(self, request): 
     if request.path == settings.LOGIN_URL and request.GET.has_key('next'): 
      return HttpResponseRedirect(settings.LOGIN_URL) 

而且,然後添加導入路徑,中間件MIDDLEWARE_CLASSES。請記住,在請求階段,換句話說,中間件首先被處理或者從上到下被處理。這應該在請求階段相對較早,但您可能需要花一點時間才能看到可以和不可以到達的內容。

這種方法唯一真正的問題是它「打破」了下一個重定向功能,而不是以一種非常直觀的方式,如果後來的開發者繼承你的代碼庫以及允許重定向的任務,它可能是一個bit flummoxing。

+2

對象的has_key已被棄用。請使用'in'代替。 –

+0

@PatrickBassut它不被棄用,它在Python 3中完全刪除。我已經更新了python3兼容的答案。 Python 2已經過時,我想知道爲什麼人們仍然在2017年使用它。 –

34

是不是隻是單純的爲:

@decorators.login_required(redirect_field_name=None) 
+0

你真的嘗試過嗎?這是幾個月前,但我認爲我嘗試了redirect_url = None,它不起作用。 – Abe

+2

是的,我嘗試過使用當前版本的Django。請注意,該參數是'redirect_field_name'而不是'redirect_url'。 – Danosaure

+0

是標準@login_required功能的一部分嗎?我在django文檔中找不到任何引用https://docs.djangoproject.com/en/1.5/topics/auth/default/#the-login-required-decorator – bab

0
login(request, user) 
if request.POST['next']: 
    return redirect(request.POST['next']) 
else: 
    msg = u"Welcome..." 
    return render_to_response('members/welcome.html', {'msg':msg}, 
               context_instance=RequestContext(request)) 
+1

最好添加一些上下文來解釋你的答案,而不僅僅是裸露的代碼。這使得它不僅對這位提問者有用,而且對將來也可能有同樣問題的任何人都更有幫助。有關更多信息,請參見[如何編寫一個好答案](http://stackoverflow.com/help/how-to-answer)上的這些指南。 – starsplusplus

相關問題