Django allauth中password_set信号失效问题求助
password_set Signal Not Triggering for Custom Password Set View Hey there, let's figure out why your password_set signal isn't firing and how to get that post-password-set login redirect working.
First, the core issue: Django's built-in password_set signal only gets sent when you use Django's official password-setting views (like SetPasswordView). Since you've written a custom setPassword view that calls user.set_password() and user.save() manually, Django won't automatically send that signal for you. On top of that, your signal receiver function had the wrong parameter order, which would have prevented it from running even if the signal was sent.
Let's break down the fixes:
Option 1: Manually Send the password_set Signal
If you want to keep using the signal approach, you need to trigger the signal yourself after saving the new password in your view. Also, fix the receiver's parameter order to match what the signal expects.
Updated views.py:
from django.contrib.auth.signals import password_set from django.dispatch import receiver from django.http import JsonResponse from django.contrib.auth.models import User from .models import Profile from django.core.exceptions import ImmediateHttpResponse from django.shortcuts import render from django.contrib.auth import logout @receiver(user_logged_in) def getFirstTimePass(user, request, **kwargs): # This works as expected if user.profile.provider != '' and user.profile.firstTimeLogin: user.profile.firstTimeLogin = False user.profile.save() raise ImmediateHttpResponse(render(request, 'index.html', {'type': user.profile.provider, 'email': user.email})) # Fixed receiver parameter order: sender first, then user, then request @receiver(password_set) def loginAfterPassChange(sender, user, request=None, **kwargs): print("Signal triggered! 🎉") # Test if this prints in your console # Store a message in session to pass to frontend request.session['post_password_msg'] = 'Please login with your new password.' def setPassword(request): data = {'errMsg': 'Something went wrong.'} if not request.user.has_usable_password(): password = request.POST.get('password') request.user.set_password(password) request.user.save() # Manually send the password_set signal password_set.send(sender=User, user=request.user, request=request) # Optional: Log the user out immediately (Django doesn't do this automatically) logout(request) data['errMsg'] = '' data['redirect_to_login'] = True return JsonResponse(data)
Option 2: Handle Logic Directly in the View (Simpler!)
Signals can add unnecessary complexity here. Since you already control the password-setting flow in your custom view, just handle the login prompt/redirect logic directly there. This is more straightforward and avoids signal-related bugs.
Updated setPassword view:
from django.contrib.auth import logout def setPassword(request): data = {'errMsg': 'Something went wrong.'} if not request.user.has_usable_password(): password = request.POST.get('password') request.user.set_password(password) request.user.save() # Log the user out so they have to re-login with the new password logout(request) data['errMsg'] = '' # Send data to frontend to trigger login dialog data['msg'] = 'Please login with your new password.' data['redirect_to_login'] = True return JsonResponse(data)
Then, in your frontend code, check for redirect_to_login: true in the response and show the login dialog or redirect to your login page.
Key Notes to Remember
- Django doesn't auto-log users out after
set_password(): You have to calllogout(request)manually if you want the user to re-authenticate with their new password. - Signal parameter order matters: The
password_setsignal sendssender,user, andrequest(optional) in that order. Your original receiver hadrequestfirst, which meant it couldn't match the signal's arguments. - Signals vs direct view logic: For simple post-action tasks like this, handling it directly in the view is usually better—it's easier to debug and maintain.
Either of these approaches should get your post-password-set login prompt working correctly.
内容的提问来源于stack exchange,提问作者Ahtisham

