Django 4.0重置密码链接指向旧表单,如何改为allauth表单地址?
问题描述
近期将项目升级至Django 4.0,同时升级了django-allauth与dj-rest-auth。当用户在http://localhost:8000/api/dj-rest-auth/password/reset/提交密码重置表单后,控制台生成的链接为http://localhost:8000/users/reset/2n/bxggn2-05019c81f9d6dfda6a10b7cfec09e839/,该链接指向旧版Django内置的密码重置表单。希望控制台输出的链接指向django-allauth的密码重置表单地址accounts/password/reset/key/1-set-password/。
以下是当前的配置文件:
settings.py
INSTALLED_APPS = [ # Local, 'api.apps.ApiConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.humanize', 'django.contrib.sessions', 'django.contrib.messages', 'whitenoise.runserver_nostatic', 'django.contrib.staticfiles', 'django.contrib.sites', 'users', # 3rd Party 'rest_framework', 'rest_framework.authtoken', 'allauth', 'allauth.account', 'allauth.socialaccount', 'dj_rest_auth', 'dj_rest_auth.registration', 'corsheaders', 'drf_yasg', ] AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.ModelBackend', 'allauth.account.auth_backends.AuthenticationBackend', ] REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAdminUser', 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', ], 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema' }
urls.py
from django.urls import path, include from allauth.account.views import ConfirmEmailView, EmailVerificationSentView urlpatterns = [ path('accounts/', include('allauth.urls')), path('', include('users.urls')), path('api/', include('api.urls')), path('api-auth/', include('rest_framework.urls')), path('api/dj-rest-auth/registration/account-confirm-email/<str:key>/', ConfirmEmailView.as_view()), # Needs to be defined before the registration path path('api/dj-rest-auth/', include('dj_rest_auth.urls')), path('api/dj-rest-auth/registration/', include('dj_rest_auth.registration.urls')), path('api/rest-auth/registration/account-confirm-email/', EmailVerificationSentView.as_view(), name='account_email_verification_sent'), path('', include('django.contrib.auth.urls')), path('users/', include('users.urls')), path('users/', include('django.contrib.auth.urls')), ]
解决方案
dj-rest-auth默认使用Django内置的密码重置流程生成链接,要替换为allauth的表单地址,需要自定义密码重置序列化器并调整配置:
- 创建自定义序列化器
在users应用下新建serializers.py,添加以下代码:
from dj_rest_auth.serializers import PasswordResetSerializer from allauth.account.forms import ResetPasswordForm from django.conf import settings class AllauthPasswordResetSerializer(PasswordResetSerializer): password_reset_form_class = ResetPasswordForm def get_email_options(self): return { 'domain_override': settings.SITE_DOMAIN, 'html_email_template_name': 'account/email/password_reset_key.html', 'email_template_name': 'account/email/password_reset_key.txt', }
- 配置使用自定义序列化器
在settings.py中添加以下配置:
REST_AUTH = { 'PASSWORD_RESET_SERIALIZER': 'users.serializers.AllauthPasswordResetSerializer', } # 确保站点配置正确 SITE_ID = 1 SITE_DOMAIN = 'localhost:8000'
- 清理冲突路由
移除urls.py中引用旧版Django auth路由的代码,避免路由冲突:
# 删除这两行: # path('', include('django.contrib.auth.urls')), # path('users/', include('django.contrib.auth.urls')),
- 验证效果
重启服务后再次提交密码重置请求,控制台生成的链接将指向allauth的密码重置表单地址http://localhost:8000/accounts/password/reset/key/.../。
原理说明:通过替换dj-rest-auth的密码重置序列化器,使用allauth的ResetPasswordForm生成重置链接,该表单默认会调用allauth的路由地址,同时正确的站点配置能保证链接域名无误。
内容的提问来源于stack exchange,提问作者spidey677
相关产品推荐
相关产品推荐

