Django忘记密码电子邮件系统期间的NoReverseMatch错误

Posted

技术标签:

【中文标题】Django忘记密码电子邮件系统期间的NoReverseMatch错误【英文标题】:NoReverseMatch errors during Django forgot password email system 【发布时间】:2018-07-21 16:34:21 【问题描述】:

我正在尝试创建一个用于通过电子邮件重置忘记密码的系统,但遇到了一些错误。

我的网址是:

from django.contrib.auth import views as auth_views

urlpatterns = [
    url(r'^$', auth_views.login, name='login'),
    url(r'^logout/$', auth_views.logout, name='logout'),
    ## more irrelevant urls here ##
    url(r'^password/reset/done/$', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    url(r'^password/reset/$', auth_views.PasswordResetView.as_view(), name='password_reset'),
    url(r'^password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]1,13-[0-9A-Za-z]1,20)/$', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    url(r'^password/reset/complete/$', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]

password_reset 提交电子邮件地址时,电子邮件发送但我收到此错误:

Internal Server Error: /password/reset/
Traceback (most recent call last):
  File "C:\python\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
    response = get_response(request)
  File "C:\python\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\python\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\python\lib\site-packages\django\views\generic\base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\python\lib\site-packages\django\utils\decorators.py", line 67, in _wrapper
    return bound_func(*args, **kwargs)
  File "C:\python\lib\site-packages\django\utils\decorators.py", line 149, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "C:\python\lib\site-packages\django\utils\decorators.py", line 63, in bound_func
    return func.__get__(self, type(self))(*args2, **kwargs2)
  File "C:\python\lib\site-packages\django\contrib\auth\views.py", line 439, in dispatch
    return super(PasswordResetView, self).dispatch(*args, **kwargs)
  File "C:\python\lib\site-packages\django\views\generic\base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\python\lib\site-packages\django\views\generic\edit.py", line 183, in post
    return self.form_valid(form)
  File "C:\python\lib\site-packages\django\contrib\auth\views.py", line 453, in form_valid
    return super(PasswordResetView, self).form_valid(form)
  File "C:\python\lib\site-packages\django\views\generic\edit.py", line 79, in form_valid
    return HttpResponseRedirect(self.get_success_url())
  File "C:\python\lib\site-packages\django\views\generic\edit.py", line 67, in get_success_url
    if self.success_url:
  File "C:\python\lib\site-packages\django\utils\functional.py", line 114, in __wrapper__
    res = func(*self.__args, **self.__kw)
  File "C:\python\lib\site-packages\django\urls\base.py", line 91, in reverse
    return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
  File "C:\python\lib\site-packages\django\urls\resolvers.py", line 497, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_done' not found. 'password_reset_done' is not a valid view function or pattern name.
[11/Feb/2018 14:32:04] "POST /password/reset/ HTTP/1.1" 500 121086

当我将链接复制到浏览器并重置密码时,密码重置正确但出现以下错误:

Internal Server Error: /password/reset/MQ/set-password/
Traceback (most recent call last):
  File "C:\python\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
    response = get_response(request)
  File "C:\python\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\python\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\python\lib\site-packages\django\views\generic\base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\python\lib\site-packages\django\utils\decorators.py", line 67, in _wrapper
    return bound_func(*args, **kwargs)
  File "C:\python\lib\site-packages\django\views\decorators\debug.py", line 76, in sensitive_post_parameters_wrapper
    return view(request, *args, **kwargs)
  File "C:\python\lib\site-packages\django\utils\decorators.py", line 63, in bound_func
    return func.__get__(self, type(self))(*args2, **kwargs2)
  File "C:\python\lib\site-packages\django\utils\decorators.py", line 67, in _wrapper
    return bound_func(*args, **kwargs)
  File "C:\python\lib\site-packages\django\views\decorators\cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "C:\python\lib\site-packages\django\utils\decorators.py", line 63, in bound_func
    return func.__get__(self, type(self))(*args2, **kwargs2)
  File "C:\python\lib\site-packages\django\contrib\auth\views.py", line 489, in dispatch
    return super(PasswordResetConfirmView, self).dispatch(*args, **kwargs)
  File "C:\python\lib\site-packages\django\views\generic\base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\python\lib\site-packages\django\views\generic\edit.py", line 183, in post
    return self.form_valid(form)
  File "C:\python\lib\site-packages\django\contrib\auth\views.py", line 522, in form_valid
    return super(PasswordResetConfirmView, self).form_valid(form)
  File "C:\python\lib\site-packages\django\views\generic\edit.py", line 79, in form_valid
    return HttpResponseRedirect(self.get_success_url())
  File "C:\python\lib\site-packages\django\views\generic\edit.py", line 67, in get_success_url
    if self.success_url:
  File "C:\python\lib\site-packages\django\utils\functional.py", line 114, in __wrapper__
    res = func(*self.__args, **self.__kw)
  File "C:\python\lib\site-packages\django\urls\base.py", line 91, in reverse
    return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
  File "C:\python\lib\site-packages\django\urls\resolvers.py", line 497, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_complete' not found. 'password_reset_complete' is not a valid view function or pattern name.
[11/Feb/2018 14:37:16] "POST /password/reset/MQ/set-password/ HTTP/1.1" 500 134868

技术上是系统功能,但显然这些错误信息并不理想。

以下是我对此提出的其他问题:

NoReverseMatch error with password reset emails

Error with system for email password resets

这就是我关注的tutorial。

【问题讨论】:

也许你的应用中有这个 url 文件? @LeLouch 是的,它在一个名为选举的应用程序中。不应该吗? 您链接到的教程不使用基于类的视图..?还注意到 /password/reset/MQ/set-password/ 与您的 password_reset_confirm 网址匹配... @thebjorn 在切换到基于类的视图之前,我遇到了 NoReverseMatch 错误。我相当肯定使用这些视图的基于类的版本不是这些错误的原因。另外,网址不应该匹配吗? 好吧,因为我看不到你的文件结构和完整的 url,所以在你的主 url 文件中包含这个 url 应该可以解决你的问题 【参考方案1】:

您没有得到反向匹配,因为 password_reset 函数重定向到 ('password_reset_done') 而不是您的应用命名空间 有关详细信息,您可以查看here 中的文档

例如,如果您的选举应用程序的包含 url 看起来像这样:

urlpatterns = [
    url(r'election', include(election.urls, namespace="SomeName")),

]

您可以通过删除包含 url 中的名称/命名空间来解决问题,或者您需要覆盖 password_reset 函数。 从 django.contrib.auth.view 导入密码重置

#views.py
def new_password_reset(password_reset):
    if post_reset_redirect is None:
        post_reset_redirect = reverse('SomeName:password_reset_done')

    return TemplateResponse(request, template_name, context) 

#urls.py
from election import views as election_views
#and in your urls change that url:
url(r'^password_reset/$', auth_views.password_reset, name='password_reset')

#with that url :
url(r'^password_reset/$', election_views.new_password_reset, name='password_reset')

你应该没事的

【讨论】:

【参考方案2】:

我不知道这在较新的 Django 中是否仍然可行,但在以前的版本中我们已经这样做了:

# django login views
urlpatterns += patterns(
    'django.contrib.auth.views',
    url(r'^logout/$',
        'logout',
        dict(
            template_name='my/logout.html',
            redirect_field_name='next',
        )),

    url(r'^password-reset/$',
        'password_reset',
        dict(
            template_name='my/password-reset-form.html',
            email_template_name='my/password-reset-email.html',
            subject_template_name='my/password-reset-email-subject.html',
            from_email=settings.FROM_EPOST,
        ),
        name="my-password-reset"),

    url(r'^password-reset-done/$',
        'password_reset_done',
        dict(
            template_name='my/password-reset-done.html',
        )),

    url(r'^password-reset-confirm/(?P<uidb64>.+)/(?P<token>.+)/$',
        'password_reset_confirm',
        dict(
            template_name='my/password-reset-confirm.html',
            # post_reset_redirect='url',
        )),

    url(r'^password-reset-complete/$',
        'password_reset_complete',
        dict(
            template_name='my/password-reset-complete.html',
        )),
)

我似乎记得在这些网址中有斜杠是个问题,但我已经很久没有写这些了..

电子邮件模板包含:

% block reset_link %
 protocol :// domain % url 'django.contrib.auth.views.password_reset_confirm' uidb64=uid token=token %
% endblock %

【讨论】:

以上是关于Django忘记密码电子邮件系统期间的NoReverseMatch错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 ReactJS 实现忘记密码/电子邮件验证 django rest

Django 电子邮件服务

忘记了来自 aws cognito 的密码链接

django 开发忘记密码通过邮箱找回功能

ad账号密码忘记怎么办

如何为没有附加外部通信方法的帐户创建密码重设系统?