Pytanie Przekieruj użytkownika do innego adresu URL z sygnałem logowania django-allauth


Używam Django-allauth do moich informacji związanych z logowaniem / rejestracją, więc gdy użytkownik zarejestruje się (pierwszy raz) w mojej witrynie, przekierowuję go do /thanks/ stronę, definiując poniżej ustawienie settings.py plik

LOGIN_REDIRECT_URL = '/ thanks /'

Ale kiedy użytkownik próbował się zalogować po raz kolejny (jeśli jest już zarejestrowany), powinienem go przekierować '/dashboard/' URL

Próbowałem to zmienić Django-allauth signals jak poniżej, który w ogóle nie działa

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

Więc może ktoś proszę daj mi znać, jak przekierować użytkownika /dashboard/ dla normalnego logowania, czy robię coś złego w powyższym kodzie sygnału?

Edytować

Po pewnych modyfikacjach zgodnie z poniższą odpowiedzią pennersr, mój AccountAdapter klasa wygląda jak poniżej

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

Ale nadal przekierowuje użytkownika do /dashboard/, moja logika określania pierwszego użytkownika jest błędna?


21
2017-11-22 06:00


pochodzenie




Odpowiedzi:


Ogólnie rzecz biorąc, nie powinieneś próbować umieszczać takiej logiki w procederze obsługi sygnału. Co zrobić, jeśli istnieje wiele programów obsługi, które chcą sterować w różnych kierunkach?

Zamiast tego wykonaj następujące czynności:

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

21
2017-11-22 11:14



Dzięki pennersr, redagowałem mój anser powyżej, czy możesz mi pomóc z tym? - shiva krishna
Czy możemy również zapewnić użytkownikowi opcję ponownego wysłania wiadomości e-mail z potwierdzeniem? jeśli nie potwierdzone, kiedy się zarejestrował? - shiva krishna
Czy próbowałeś sprawdzić wartości last_login / date_joined? Ponowne wysyłanie e-maili potwierdzających odbywa się automatycznie, gdy tylko użytkownik spróbuje zalogować się przy użyciu niezweryfikowanego e-maila. Zauważ, że w celu uniknięcia bombardowań pocztą, jest to możliwe tylko wtedy, gdy próby logowania są oddalone o 3 minuty. - pennersr
Nie nadawaj nowego pliku "project /.../ allauth.py", a następnie załaduje go najpierw w ścieżce i zamaskuje całą bibliotekę allauth wyrzucając wyjątek ImportError. - eezis
@pennersr nie miałbyś nic przeciwko, aby mi pomóc w kwestii wymienionych tutaj stackoverflow.com/questions/24885732/... - Lionel


Dwa datetimes last_login i date_joined zawsze będzie inny, chociaż może to być tylko kilka milisekund. Ten fragment kodu działa:

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

Jeden ważna uwaga do pennersr odpowiedź: UNIKNĄĆ używanie plików o nazwach allauth.py ponieważ będzie mylić Django i prowadzić do błędy importu.


6
2018-02-27 07:54



Dzięki, to było pomocne - shiva krishna
@ user2292376 Myślę, że assert jest tutaj niepotrzebne, ponieważ jest to przekierowanie logowania, więc użytkownik powinien zostać uwierzytelniony w tym momencie. Jednak +1 - Caumons
@ DH1TW wierzę, że to rozwiązanie nie jest całkowicie zgodne z kulą ... Właśnie zdałem sobie sprawę, że jeśli użytkownik spróbuje nieudanego logowania (nieprawidłowe hasło), request.user.last_login wciąż jest aktualizowany z jakiegoś powodu, więc request.user.last_login! = request.user.date_joined i nawet próg nie może go zapisać .. czy macie jakieś rozwiązanie? - psychok7


Możesz po prostu zdefiniować te dwa inne sygnały za pomocą user_logged_in sygnał jako baza. Dobre miejsce na umieszczenie go jest na signals.py wewnątrz a konta aplikacja, na wypadek, gdy ją masz, lub w tobie rdzeń aplikacja. Pamiętaj tylko, aby zaimportować signals.py w Tobie __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

0
2017-12-14 13:18