未找到带有参数“()”和关键字参数“”的“password_change_done”的反向

Posted

技术标签:

【中文标题】未找到带有参数“()”和关键字参数“”的“password_change_done”的反向【英文标题】: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 个模式:[]

我尝试了什么

我不知道为什么会这样。

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

感谢任何帮助。谢谢!

【问题讨论】:

当我将 name='userauth_password_change_done' 的名称更改为 name='password_change_done' 时,它可以工作。这是为什么?有人可以解释一下吗? 【参考方案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'),
]

【讨论】:

以上是关于未找到带有参数“()”和关键字参数“”的“password_change_done”的反向的主要内容,如果未能解决你的问题,请参考以下文章

未找到带有参数“(”,)”和关键字参数“”的“比率”的反向

未找到带有参数“()”和关键字参数“”的“登录”的反向操作

未找到带有参数“()”和关键字参数“”的“password_change_done”的反向

未找到带有参数“()”和关键字参数“”的“send_referral_code”的反向

未找到带有参数“()”和关键字参数“”的“guestbook.posts”的反向操作。尝试了 0 种模式:[]

未找到带有参数“()”和关键字参数“'pk':6”的“post_edit”的反向。尝试了 0 种模式:[]