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

Django1.6自定义密码重置确认表单与视图报错排查

解决Django 1.6自定义密码重置确认流程的问题

我来帮你一步步解决遇到的两个核心问题:SetPasswordForm无set_cookie属性错误,以及完成整个密码重置确认流程。


这个错误的根源在于视图配置和请求处理逻辑的几个小问题,我们逐个修正:

1. 修正success_url配置

你当前把success_url设为模板路径(registration/password_reset_complete.html),这是错误的——FormView的success_url需要指向URL路径或URL名称,而非模板文件。

首先在urls.py中添加密码重置完成页的URL配置:

from django.views.generic.base import TemplateView

url(r'^account/password_reset_complete/$', TemplateView.as_view(template_name='registration/password_reset_complete.html'), name='password_reset_complete'),

然后在PasswordResetConfirmView中用reverse_lazy获取这个URL:

from django.core.urlresolvers import reverse_lazy

class PasswordResetConfirmView(FormView):
    template_name = "registration/password_reset_confirm.html"
    success_url = reverse_lazy('password_reset_complete')  # 替换原来的模板路径
    form_class = SetPasswordForm
    # ... 其他代码保持不变

2. 替换form_valid的调用逻辑

你已经手动完成了密码保存的逻辑,不需要依赖FormView默认的form_valid方法。在post方法的form.is_valid()分支里,把return self.form_valid(form)改成直接返回重定向响应:

return HttpResponseRedirect(self.get_success_url())

这能避免FormView内部可能的错误调用,也符合你已经完成表单处理的逻辑。

3. 处理GET请求的token验证

用户点击重置链接是GET请求,你当前只在POST方法中验证token,导致未验证就显示表单。给视图添加get方法,先验证链接有效性再显示表单:

from django.core.urlresolvers import reverse

def get(self, request, uidb64=None, token=None, *args, **kwargs):
    UserModel = get_user_model()
    try:
        uid = urlsafe_base64_decode(uidb64)
        user = UserModel._default_manager.get(pk=uid)
    except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
        user = None

    if user is not None and default_token_generator.check_token(user, token):
        # 链接有效,显示重置表单
        return super(PasswordResetConfirmView, self).get(request, *args, **kwargs)
    else:
        # 链接无效,返回重置页面并提示错误
        messages.error(request, 'The reset password link is no longer valid.')
        return HttpResponseRedirect(reverse('reset_password'))

二、解决Django 1.6无update_session_auth_hash的问题

Django 1.6没有内置的update_session_auth_hash方法,我们可以手动模拟这个功能,确保用户修改密码后当前session仍然有效,同时更新认证哈希值提升安全性。

在user.save()之后添加以下代码:

from django.contrib.auth import SESSION_KEY, BACKEND_SESSION_KEY, HASH_SESSION_KEY
from django.contrib.auth import get_backends

# 更新session中的用户认证信息
request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
request.session[BACKEND_SESSION_KEY] = get_backends()[0].__class__.__name__
request.session[HASH_SESSION_KEY] = user.get_session_auth_hash()

这段代码和Django 1.7+的update_session_auth_hash功能一致,能避免用户修改密码后session失效的问题。


三、修正urls.py的其他错误

你当前的reset_password_doneURL指向了ResetPasswordRequestView,这是错误的——这个页面应该是显示“重置邮件已发送”的提示页,改成TemplateView:

url(r'^account/password/reset/done/$', TemplateView.as_view(template_name='registration/password_reset_done.html'), name="reset_password_done"),

完成以上修改后,你的自定义密码重置确认流程应该就能正常工作了:用户点击重置链接后先验证有效性,验证通过后显示密码重置表单,提交后保存新密码并更新session,最后跳转到重置完成页。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:57:36