You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用自定义change_password.html替换Django Admin密码重置页并跳转登录

问题分析

从终端请求日志能看到,用户点击重置链接后访问的是 /reset/... 路径,而非你自定义的 /users/password-reset-confirm/...。原因是默认的 PasswordResetView 生成重置邮件时,用的是 Django auth 模块自带的 password_reset_confirm 命名路由(对应 /reset/ 路径),不是你在 users 应用中定义的带命名空间的路由。另外,你希望重置完成后跳转到登录页,当前配置的是跳转到 password_reset_complete,也需要调整。

解决方案

1. 自定义 PasswordResetView,生成带命名空间的重置链接

默认视图生成的链接指向 auth 模块的路由,我们需要继承 PasswordResetView,修改链接生成逻辑,指向 users 应用的重置确认路由。

在 users/views.py 中添加:

from django.contrib.auth.views import PasswordResetView
from django.urls import reverse_lazy
from django.utils.http import urlsafe_base64_encode
from django.contrib.auth.tokens import default_token_generator
from django.utils.encoding import force_bytes

class CustomPasswordResetView(PasswordResetView):
    def get_reset_url(self, user):
        # 生成指向 users 应用的重置确认链接
        uid = urlsafe_base64_encode(force_bytes(user.pk))
        token = default_token_generator.make_token(user)
        return reverse_lazy('users:password_reset_confirm', kwargs={'uidb64': uid, 'token': token})

若你的 Django 版本低于 3.1(get_reset_url 是 3.1 新增方法),请改用以下代码重写 send_mail:

class CustomPasswordResetView(PasswordResetView):
    def send_mail(self, subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None):
        user = context['user']
        uid = urlsafe_base64_encode(force_bytes(user.pk))
        token = default_token_generator.make_token(user)
        # 替换 context 中的重置链接为带命名空间的版本
        context['reset_url'] = reverse_lazy('users:password_reset_confirm', kwargs={'uidb64': uid, 'token': token})
        super().send_mail(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name)

2. 更新 users/urls.py 路由配置

  • 替换默认的 PasswordResetView 为自定义视图
  • 修改 PasswordResetConfirmView 的 success_url,使其跳转到登录页

修改后的 users/urls.py:

app_name = 'users'

from django.contrib.auth import views as auth_views
from . import views
from .views import CustomPasswordResetView

urlpatterns = [
    path('password/', views.change_password, name='change_password'),
    # 使用自定义视图生成正确的重置链接
    path('password-reset/', CustomPasswordResetView.as_view(
        template_name='users/password_reset.html',
        success_url=reverse_lazy('users:password_reset_done')
    ), name='password_reset'),
    path('password-reset/done/', auth_views.PasswordResetDoneView.as_view(
        template_name='users/password_reset_done.html'
    ), name='password_reset_done'),
    # 重置完成后跳转到登录页
    path('password-reset-confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(
        template_name='users/change_password.html',
        success_url=reverse_lazy('login')
    ), name='password_reset_confirm'),
    # 若不需要重置完成提示页,可删除以下路由
    path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view(
        template_name='users/password_reset_complete.html'
    ), name='password_reset_complete'),
]

3. 调整主项目 urls.py 路由顺序(可选)

将 users 应用的路由放在 django.contrib.auth.urls 之前,避免命名路由优先级冲突:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('users/', include('users.urls')),
    path('', include('django.contrib.auth.urls')),
]

4. 验证模板路径

确保 change_password.html 位于 users/templates/users/ 目录下,Django 能正确加载该模板。

原理说明

  • 自定义 CustomPasswordResetView 重写了链接生成逻辑,让邮件中的重置地址指向你自定义的路由
  • 修改 PasswordResetConfirmView 的 success_url 为 login 命名路由,实现重置后直接跳转登录页
  • 调整主路由顺序可避免 auth 模块的默认路由优先匹配,确保自定义路由生效

内容的提问来源于stack exchange,提问作者A_K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:39:21