简体   繁体   English

使用 django-allauth 登录信号将用户重定向到另一个 url

[英]Redirect User to another url with django-allauth log in signal

I am using Django-allauth for my login/signup related stuff, so when a user signs up(first time) into my site, I am redirecting him to /thanks/ page by defining below setting in settings.py file我将 Django-allauth 用于我的登录/注册相关内容,因此当用户注册(第一次)到我的网站时,我通过在settings.py文件中定义以下设置将他重定向到/thanks/页面

LOGIN_REDIRECT_URL = '/thanks/' LOGIN_REDIRECT_URL = '/thanks/'

But when the user tried to log in for the next time(if already registered) I should redirect him to '/dashboard/' URL但是当用户下次尝试登录时(如果已经注册)我应该将他重定向到'/dashboard/' URL

So tried to alter that with Django-allauth signals like below which is not working at all所以试图用Django-allauth signals改变它,如下所示,它根本不起作用

@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'))

So can anyone please let me know how to redirect a user to /dashboard/ for the normal login, am I doing anything wrong in the above signal code?那么任何人都可以让我知道如何将用户重定向到/dashboard/以进行正常登录,我在上面的信号代码中做错了什么吗?

Edit编辑

After some modification according to the below answer by pennersr , my AccountAdapter class looks like below根据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/'

But still, it is redirecting the user to /dashboard/ , my logic in determining the first time user is wrong?但是,它仍然将用户重定向到/dashboard/ ,我确定第一次用户的逻辑是错误的?

In general, you should not try to put such logic in a signal handler.通常,您不应尝试将此类逻辑放入信号处理程序中。 What if there are multiple handlers that want to steer in different directions?如果有多个处理程序想要转向不同方向怎么办?

Instead, do this:相反,请执行以下操作:

# 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/'

The two datetimes last_login and date_joined will always be different, although it might only be a few milliseconds. last_logindate_joined这两个日期last_login总是不同的,尽管它可能只有几毫秒。 This snippet works:这个片段有效:

# 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)

One important remark to pennersr answer: AVOID using files named allauth.py as it will confuse Django and lead to import errors .对 pennersr 回答的一个重要评论避免使用名为allauth.py 的文件,因为它会混淆 Django 并导致导入错误

You can simply define those two other signals using user_logged_in signal as base.您可以使用user_logged_in信号作为基础简单地定义这两个其他信号。 A good place to put it is on a signals.py inside a accounts app, in case you have one, or in you core app.一个放置它的好地方是在帐户应用程序中的signals.py 上,如果您有一个,或者在您的核心应用程序中。 Just remember to import signals.py in you __init__.py .只要记住你的__init__.py导入signals.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'


@receiver(post_user_first_login)
def handle_post_user_first_login(sender, user, request, **kwargs):
    print 'post_user_first_login'

the answer here is very simple, you do not need any signals or overriding the DefaultAccountAdapter in settings.py just add a signup redirect_url这里的答案很简单,您不需要任何信号或覆盖settings.pyDefaultAccountAdapter只需添加一个注册 redirect_url

ACCOUNT_SIGNUP_REDIRECT_URL = "/thanks/"
LOGIN_REDIRECT_URL = "/dashboard/"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM