2013-11-22 103 views
19

我爲我的登錄/註冊相關內容使用Django-allauth,所以當用戶註冊(第一次)到我的網站時,我將他重定向到/thanks/頁面在settings.py文件中定義如下設置用django-allauth登錄信號將用戶重定向到另一個網址

LOGIN_REDIRECT_URL =「/謝謝/」

但是,當用戶試圖登錄,在未來的時間(如果已經註冊),我要他重定向到'/dashboard/' URL

所以試圖改變Django-allauth signals像下面這是不workin處的G所有

@receiver(allauth.account.signals.user_logged_in) 
def registered_user_login(sender, **kwargs): 
    instance = User.objects.get_by_natural_key(kwargs['user']) 
    print instance.last_login==instance.date_joined,"??????????????????????????????" 
    if not instance.last_login==instance.date_joined: 
     return HttpResponseRedirect(reverse('dashboard')) 

因此,誰能請讓我知道如何將用戶重定向到/dashboard/爲正常登錄,我在做什麼錯在上面的信號代碼?

編輯

後按照下面的答案被pennersr一些修改,我AccountAdapter類看起來像下面

from allauth.account.adapter import DefaultAccountAdapter 
# from django.contrib.auth.models import User 

class AccountAdapter(DefaultAccountAdapter): 

    def get_login_redirect_url(self, request): 
    if request.user.last_login == request.user.date_joined: 
     return '/registration/success/' 
    else: 
     return '/dashboard/' 

但儘管如此,它是將用戶重定向到/dashboard/,我的邏輯在確定第一次用戶錯了?

回答

19

一般來說,你不應該試圖把這樣的邏輯放在信號處理程序中。如果有多個處理程序想要轉向不同的方向怎麼辦?

相反,這樣做:

# settings.py: 
ACCOUNT_ADAPTER = 'project.users.allauth.AccountAdapter' 


# project/users/allauth.py: 
class AccountAdapter(DefaultAccountAdapter): 

    def get_login_redirect_url(self, request): 
     return '/some/url/' 
+0

謝謝pennersr,我上面編輯過我的anser,你能幫我解決嗎? –

+0

我們也可以爲用戶提供重新發送確認電子郵件的選項嗎?如果他沒有確認登記? –

+0

您是否嘗試過檢查last_login/date_joined的值?只要用戶嘗試使用未經驗證的電子郵件登錄,就會自動重新發送確認電子郵件。請注意,爲了防止郵件轟炸,只有當登錄嘗試間隔3分鐘左右時纔會進行。 – pennersr

6

兩個日期時間last_logindate_joined將永遠是不同的,儘管它可能只有幾毫秒。這段代碼的工作原理:

# settings.py: 
ACCOUNT_ADAPTER = 'yourapp.adapter.AccountAdapter' 

# yourapp/adapter.py: 
from allauth.account.adapter import DefaultAccountAdapter 
from django.conf import settings 
from django.shortcuts import resolve_url 
from datetime import datetime, timedelta 

class AccountAdapter(DefaultAccountAdapter): 

    def get_login_redirect_url(self, request): 
     threshold = 90 #seconds 

     assert request.user.is_authenticated() 
     if (request.user.last_login - request.user.date_joined).seconds < threshold: 
      url = '/registration/success' 
     else: 
      url = settings.LOGIN_REDIRECT_URL 
     return resolve_url(url) 

一個重要提示到pennersr答案:AVOID使用的文件名爲allauth.py,因爲它會混淆Django和導致導入錯誤

+0

謝謝,這是有幫助的 –

+0

@ user2292376我認爲'assert'在這裏是不必要的,因爲這是一個登錄重定向,所以用戶應該在被調用的地方進行身份驗證。然而,+1 – Caumons

+0

@ DH​​1TW我相信這個解決方案並不完全是防彈的......我只是意識到,如果用戶嘗試登錄失敗(密碼錯誤),request.user.last_login仍會因某種原因而更新,因此請求。 user.last_login!= request.user.date_joined,甚至沒有門檻可以保存它..你們有解決方案嗎? – psychok7

0

您可以簡單地使用user_logged_in信號作爲基準來定義這兩個其他信號。一個好地方,就是signals.py裏面的一個帳戶應用程序,如果你有一個,或在你的核心應用程序。只記得導入signals.py__init__.py

from django.dispatch import receiver, Signal 

pre_user_first_login = Signal(providing_args=['request', 'user']) 
post_user_first_login = Signal(providing_args=['request', 'user']) 


@receiver(user_logged_in) 
def handle_user_login(sender, user, request, **kwargs): 
    first_login = user.last_login is None 
    if first_login: 
     pre_user_first_login.send(sender, user=user, request=request) 
    print 'user_logged_in' 
    if first_login: 
     post_user_first_login.send(sender, user=user, request=request) 


@receiver(pre_user_first_login) 
def handle_pre_user_first_login(sender, user, request, **kwargs): 
    print 'pre_user_first_login' 
    pass 


@receiver(post_user_first_login) 
def handle_post_user_first_login(sender, user, request, **kwargs): 
    print 'post_user_first_login' 
    pass 
相關問題