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

匿名 (未验证) 提交于 2019-12-03 01:47:02

问题:

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

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

So tried to alter that with Django-allauth signals like below which is not working at all

@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?

Edit

After some modification according to the below answer by pennersr, my AccountAdapter class looks like below

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?

回答1:

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


回答2:

The two datetimes last_login and date_joined will always be different, although it might only be a few milliseconds. 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.



回答3:

You can simply define those two other signals using user_logged_in signal as base. 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. Just remember to import signals.py in you __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 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!