【问题标题】:Reverse for 'password_change_done' with arguments '()' and keyword arguments '{}' not found未找到带有参数“()”和关键字参数“{}”的“password_change_done”的反向
【发布时间】:2015-08-29 13:06:49
【问题描述】:

背景

我正在尝试自定义 Django 项目中的身份验证视图,但我似乎无法运行自定义的 password_change 视图。我使用 Django 1.8.2 和 Python 2.7。

我的模块userauthurls.py 如下所示:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('django.contrib.auth.views',
    url(r'^login/$', 'login', {'template_name': 'userauth/login.html'},
        name='userauth_login'),
    url(r'^logout/$', 'logout', {'next_page': '/'},
        name='userauth_logout'),
    url(r'^password-change/$', 'password_change',
        {'template_name': 'userauth/password_change_form.html'},
        name='userauth_password_change'),
    url(r'^password-change-done/$', 'password_change_done',
        {'template_name': 'userauth/password_change_done.html'},
        name='userauth_password_change_done'),
)

这在主要的urls.py 中被引用为:

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^account/', include('userauth.urls')),
]

userauth/password_change_form.html的模板

{% extends "base.html" %}

{% block title %}{{ block.super }} - Change Password{% endblock %}

{% block toggle_login %}{% endblock %}

{% block content %}
<form action="{% url 'userauth_password_change' %}" method="post" accept-charset="utf-8">
  {{ form.as_p }}
  {% csrf_token %}
  <input type="submit" value="Change password"/>
</form>
{% endblock %}

还有userauth/password_change_done.html的模板

{% extends "base.html" %}

{% block title %}{{ block.super }} - Password change successful{% endblock %}

{% block content %}
<p>Your password has been changed successfully.</p>
<a href="{% url 'products_product_index' %}">Back to your Account</a>
{% endblock %}

问题

当我打开'password_change_done' 页面(在/account/password-change-done)时,一切都很好。

但是在'password-change' (/accunt/password-change) 我收到了这个错误:

NoReverseMatch 位于 /account/password-change/

未找到带有参数“()”和关键字参数“{}”的“password_change_done”的反向操作。尝试了 0 个模式:[]

我尝试了什么

我不知道为什么会这样。

  1. 我尝试从url 'userauth_password_change' 中删除单引号
  2. 我确保password-change-donepage 存在于 urls.py 中并且可用
  3. 我阅读了Reverse for '*' with arguments '()' and keyword arguments '{}' not foundDjango: Reverse for 'detail' with arguments '('',)' and keyword arguments '{}' not foundDjango change_password NoReverseMatch at /accounts/password/change/ 上的解决方案(还有一些,我尝试了那里的所有解决方案,但我在自己的代码中找不到问题)

感谢任何帮助。谢谢!

【问题讨论】:

  • 当我将 name='userauth_password_change_done' 的名称更改为 name='password_change_done' 时,它可以工作。这是为什么?有人可以解释一下吗?

标签: python django django-authentication


【解决方案1】:

好的,所以我建议的解决方案在这里不起作用。我在具有特定应用程序标签的应用程序中使用 Django 1.8.8,因此我需要在这样的模板中指定一个 url,例如app_label:url_name。这意味着 password_change_done 的反面永远不会起作用,因为它是 app_label:password_change_done。

但幸运的是,有一个解决方案:“post_change_redirect”。因此,我这样指定 password_change:

url(r'^password_change$', 'django.contrib.auth.views.password_change', {'template_name': 'password_change.html', 'post_change_redirect': 'app_label:password_change_done'}, name='password_change'),

我相信其他人可以使用它来克服上述问题,并且仍然保留自己的自定义 url 名称。

【讨论】:

  • 但这看起来更像是解决方法,我可以在文档中的哪里找到它?这在 django 1.10 中已修复(因为 django 1.9 中与 1.8.8 中相同)。
【解决方案2】:

在某些部分中,您将 URL 称为“password_change_done”

正确的名称是:“userauth_password_change_done”

【讨论】:

  • 那在哪里?我找不到错误地使用它。应该改为name='password_change_done' 吗?
  • 能否添加名为“password_change”的视图?
  • 其实我没有password_change 的自定义视图。虽然它只使用'django.contrib.auth.views-password_change',但由于 lin `urlpatterns = patterns('django.contrib.auth.views',。我理解错了吗?
  • 其实反之亦然:'userauth_password_change_done'不正确 url name,它必须是'password_change_done'。感谢您的帮助,为我指明了正确的方向!
【解决方案3】:

解决方案是,在 urls.py 中,password_change_done 链接的名称必须'password_change_done'

url(r'^password-change-done/$', 'password_change_done',
    {'template_name': 'userauth/password_change_done.html'},
    name='password_change_done'),

我查看了django.contrib.auth.views.password_change(这是造成问题的原因)并意识到,URL 'password_change_done' 在 Django 1.8.2 中是硬编码的。

【讨论】:

    【解决方案4】:

    您需要删除视图名称周围的单引号

    {% url password_change_done %}
    

    而不是

    {% url 'password_change_done' %}
    

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题。原因是“password_change_done”是auth.views中的硬编码,所以我在auth.views.PasswordChangeView的基础上扩展了类。

      auth.views.PasswordChangeView:

      class PasswordChangeView(PasswordContextMixin, FormView):
      ......
      success_url = reverse_lazy('password_change_done')
      

      MyPasswordChangeView:

      class MyPasswordChangeView(PasswordChangeView):
          success_url = reverse_lazy('app_label:password_change_done')
      

      只需覆盖success_url

      并在 urlpattern 中使用 MyPasswordChangeView。现在,一切正常。

      【讨论】:

      • 更方便的方式,只需覆盖as_view()中的class var success_url:path('settings/password/', auth_views.PasswordChangeView.as_view( template_name='accounts/password_change.html', success_url=reverse_lazy('accounts:password_change_done')), name='password_change', ),
      【解决方案6】:

      如果你正在使用

      app_name

      并尝试覆盖更新/更改密码的默认模板,您必须告诉 Django:

      from django.urls import path, reverse_lazy
      from django.contrib.auth import views as auth_view
      from . import views
      
      app_name = 'account'
      
      urlpatterns = [
          path('login/', auth_view.LoginView.as_view(), name='login'),
          path('logout/', auth_view.LogoutView.as_view(), name='logout'),
      
          path('password_change/',
               auth_view.PasswordChangeView.as_view(
                   template_name='registration/password_change_form.html',
                   success_url=reverse_lazy('account:password_change_done')), name='password_change'),
      
          path('password_change/done/',
               auth_view.PasswordChangeDoneView.as_view(
                   template_name='registration/password_change_done.html'), name='password_change_done'),
      ]
      

      【讨论】:

        猜你喜欢
        • 2010-12-22
        • 2013-12-07
        • 2017-05-04
        • 2014-05-29
        • 2013-07-25
        • 2019-11-06
        • 2012-07-08
        • 2019-04-21
        相关资源
        最近更新 更多