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

Django Rest Framework密码重置确认页表单显示为None的问题排查

问题原因及修复方案

核心原因

模板中{{ form }}渲染为None,本质是PasswordResetConfirmView判定当前密码重置链接无效(validlink=False),因此未将表单对象传入模板上下文。结合DRF + dj-rest-auth的环境,主要诱因有两个:

  1. URL名称冲突:你同时引入了django.contrib.auth.urls(自带同名password_reset_confirm等URL)和自定义的密码重置URL,导致邮件生成的链接可能指向错误端点,或reverse解析时出现歧义。
  2. Token验证不兼容:若dj-rest-auth的配置覆盖了密码重置的Token生成逻辑,而你用原生Django视图验证Token,会导致校验失败,视图判定链接无效,不生成表单。

修复方法

方法1:移除冲突的URL配置

既然已经自定义了全套密码重置视图,直接删除django.contrib.auth.urls的引入,避免名称冲突:

# 主urls.py
urlpatterns = [
    # 移除这一行:path('', include('django.contrib.auth.urls')),
    path('password-reset/', auth_views.PasswordResetView.as_view(template_name='users/password_reset.html', success_url=reverse_lazy('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/password_reset_confirm.html'),name='password_reset_confirm',),
    path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view(template_name='users/password_reset_complete.html'), name='password_reset_complete'),
    path('admin/', admin.site.urls),
    path('api/', include('api.urls'), ),
    path('users/', include('users.urls'), ),
]

修改后,邮件生成的链接会明确指向你的自定义视图,消除reverse解析歧义。

方法2:验证链接有效性并调试

在模板中添加链接有效性判断,快速定位问题:

<!-- password_reset_confirm.html -->
<main class="mt-5" >
    <div class="container dark-grey-text mt-5">
        <div class="content-section">
            {% if not validlink %}
                <p>密码重置链接无效,请重新申请重置。</p>
            {% else %}
                <form method="POST">
                    {% csrf_token %}
                    <fieldset class="form-group">
                        <legend class="border-bottom mb-4">Reset Password</legend>
                        {{ form|crispy }}
                        {{ form }}
                    </fieldset>
                    <div class="form-group">
                        <button class="btn btn-outline-info" type="submit">Reset Password</button>
                    </div>
                </form>
            {% endif %}
        </div>
    </div>
</main>

如果页面显示链接无效,进一步排查:

  • 检查邮件链接路径是否为password-reset-confirm/(而非原生的password_reset_confirm/)
  • 确认自定义User模型继承AbstractUser,包含last_login等Token生成依赖字段

方法3:统一使用dj-rest-auth的密码重置流程

既然已经引入dj-rest-auth,建议直接使用它的密码重置视图,避免兼容性问题:

  1. 在主urls.py添加dj-rest-auth的密码重置URL:
urlpatterns = [
    # ... 其他URL
    path('api/password/reset/', include('dj_rest_auth.password_reset.urls')),
]
  1. 在settings.py中配置自定义模板路径:
REST_AUTH = {
    'PASSWORD_RESET_CONFIRM_TEMPLATE': 'users/password_reset_confirm.html',
    'PASSWORD_RESET_DONE_TEMPLATE': 'users/password_reset_done.html',
    # 其他配置(如邮件主题、序列化器)可按需添加
}

这样整个流程基于dj-rest-auth实现,和DRF环境完全兼容。


额外检查项

  • 确保django.contrib.sites已加入INSTALLED_APPS,并设置SITE_ID = 1(邮件链接生成依赖站点配置)
  • 验证邮件发送的链接域名是否和当前运行环境一致,避免开发/生产环境差异导致链接无效

内容的提问来源于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 09:31:05