首页 > 解决方案 > Django:解决“找不到'password_reset_complete'的反向。”

问题描述

我正在尝试使用自定义 html 模板使用 Django 进行密码重置。我可以通过电子邮件请求重置密码(使用 EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'),然后我会在控制台中收到一封“电子邮件”,如我所愿。该电子邮件确实将我引导至我想要的“password_reset_confirm.html”页面,并且我可以为与该用户关联的用户输入新密码。

但是,当我单击“重置密码!”时出现以下错误。按钮:

"Reverse for 'password_reset_complete' not found. 'password_reset_complete' is not a valid view function or pattern name."

尽管有这个错误,密码确实会改变,但是我(显然)不想要这个错误。

该项目的结构在主结构中有一个用户“应用程序”,所以它是:

项目
main_app
用户
----templates
--------注册
------------password_reset_form.html
------------password_reset_confirm.html
--- ---------password_reset_done.html
------------password_reset_email.html
------------password_reset_complete.html

我在 users 中的 urls.py 代码如下:

from django.urls import path, include, reverse_lazy

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

app_name = 'users'
urlpatterns = [
    # Default authorisation urls.
    path('', include('django.contrib.auth.urls')),
    # Registration page.
    path('register/', views.register, name='register'),
    # Password reset urls.
    path(
        'password_reset',
        auth_views.PasswordResetView.as_view(
            template_name='registration/password_reset_form.html',
            email_template_name='registration/password_reset_email.html',
            success_url=reverse_lazy('users:password_reset_done')
        ),
        name='password_reset'
    ),
    path(
        'password_reset/done/',
        auth_views.PasswordResetDoneView.as_view(template_name='registration/password_reset_done.html'),
        name='password_reset_done'
    ),
    path(
        'reset/<uidb64>/<token>/',
        auth_views.PasswordResetConfirmView.as_view(
            template_name='registration/password_reset_confirm.html',
            success_url=reverse_lazy('users:password_reset_complete.html')
        ),
        name='password_reset_confirm'
    ),
    path(
        'reset/done/',
        auth_views.PasswordResetCompleteView.as_view(template_name='registration/password_reset_complete.html'),
        name='password_reset_complete'
    ),

]

我遇到了类似的问题,但是使用“password_reset_done”,但是通过查看此站点,我能够解决此问题,方法是添加

success_url=reverse_lazy('users:password_reset_done')

到密码重置的路径,并解决了该问题,但是我随后遇到了上述问题,我还没有找到任何解决方案。将以下内容添加到 password_reset_confirmation 的路径没有帮助:

success_url=reverse_lazy('users:password_reset_complete.html')

例如,我尝试将其更改为登录页面,该页面似乎没有任何改变,并且在调查中发现我可以删除以下内容并且程序将保持不变:

    path(
        'reset/<uidb64>/<token>/',
        auth_views.PasswordResetConfirmView.as_view(
            template_name='registration/password_reset_confirm.html',
            success_url=reverse_lazy('users:password_reset_complete.html')
        ),
        name='password_reset_confirm'
    ),
    path(
        'reset/done/',
        auth_views.PasswordResetCompleteView.as_view(template_name='registration/password_reset_complete.html'),
        name='password_reset_complete'
    ),

这就是为什么在这种情况下success_url 没有改变行为的原因。我想知道 password_reset_email.html 是否是罪魁祸首,以防这导致调用“password_reset_confirm”,而不是“user:password_reset_confirm”(因为忽略了 urlpattern)。

密码重置电子邮件.html:

{% autoescape off %}
To initiate the password reset process for your account, click the link below:

{{ protocol }}://{{ domain }}{% url 'users:password_reset_confirm' uidb64=uid token=token %}
If clicking the link above doesn't, please copy and paste it into a new browser instead.

{% endautoescape %}

我还包含了 password_reset_confirm.html 代码以防万一:

{% extends "demeter_app/base.html" %}

{% block content %}
    <p>Please enter your new password:</p>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="Reset password!">
    </form>
{% endblock content %}

有人对我如何解决这个问题有任何想法吗?我试过查看 Stackoverflow,但是大多数查询与 password_reset_done 而不是password_reset_complete相关。

更多错误如下:

Environment:


Request Method: POST
Request URL: http://localhost:8000/users/reset/MQ/set-password/

Django Version: 3.1.7
Python Version: 3.9.2
Installed Applications:
['demeter_app',
 'users',
 'import_export',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\views\generic\base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\utils\decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\views\decorators\debug.py", line 89, in sensitive_post_parameters_wrapper
    return view(request, *args, **kwargs)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\utils\decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\views\decorators\cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\contrib\auth\views.py", line 272, in dispatch
    return super().dispatch(*args, **kwargs)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\views\generic\base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\views\generic\edit.py", line 142, in post
    return self.form_valid(form)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\contrib\auth\views.py", line 305, in form_valid
    return super().form_valid(form)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\views\generic\edit.py", line 57, in form_valid
    return HttpResponseRedirect(self.get_success_url())
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\views\generic\edit.py", line 51, in get_success_url
    if not self.success_url:
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\utils\functional.py", line 135, in __wrapper__
    res = func(*self.__args, **self.__kw)
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\urls\base.py", line 87, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "C:\Users\marcj\Documents\demeter\demeter_env\lib\site-packages\django\urls\resolvers.py", line 685, in _reverse_with_prefix
    raise NoReverseMatch(msg)

Exception Type: NoReverseMatch at /users/reset/MQ/set-password/
Exception Value: Reverse for 'password_reset_complete' not found. 'password_reset_complete' is not a valid view function or pattern name.

如果还有什么我可以提供的帮助,请告诉我。

标签: pythondjangodjango-urlsdjango-authentication

解决方案


它对您不起作用,因为链接顺序已损坏。首先,重新指定的应该去,然后才是标准的。为了正确操作,这样做就足够了:

urlpatterns = [
    path('password_reset/',
        auth_views.PasswordResetView.as_view(
            success_url=reverse_lazy('users:password_reset_done')), 
        name='password_reset'),
    path('reset/<uidb64>/<token>/', 
        auth_views.PasswordResetConfirmView.as_view(
            success_url=reverse_lazy('users:password_reset_complete')), 
        name='password_reset_confirm'),
    path('', include('django.contrib.auth.urls')),
]

这个命令是必要的,因为'django.contrib.auth.urls' 已经包含'reset/<uidb64>/< token>/'。结果,您的代码没有运行。


推荐阅读