Django-nonrel + Django-registration问题:重置密码时出现意外的关键字参数'uidb36'。

21

我正在使用Django-nonrelregistration应用程序。 一切似乎都很好,但当我尝试重置密码时出现问题。 点击我在电子邮件中收到的重置密码链接时,Django会产生错误消息:

password_reset_confirm() got an unexpected keyword argument 'uidb36'

我的问题是:有人见过它并知道治疗方法吗?

编辑:

问题是由 registration\auth_urls.py 引起的 - 它们在 django\contrib\auth\urls.py 中重复条目,绕过了 Django-nonrel 中修补后的文件。 有什么想法为什么会出现这种情况,我能否删除它或以其他方式修复它?

4个回答

34

Django 1.6使用base 64编码代替base 36编码来编码用户ID。

如果您有任何自定义的密码重置URL,您需要通过将uidb36替换为uidb64并将该模式后面的破折号替换为斜杠来更新它们。同时,将“_”、“\”和“-”添加到可以匹配uidb64模式的字符列表中。

例如,在Django 1.5中的urls.py中:

url(r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
    'django.contrib.auth.views.password_reset_confirm',
    name='password_reset_confirm'),

在 Django 1.6+ 版本中需要更改为:

url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
    'django.contrib.auth.views.password_reset_confirm',
    name='password_reset_confirm'),

这是官方变更日志,其中详细说明了该变更: https://docs.djangoproject.com/en/1.6/releases/1.6/#django-contrib-auth-password-reset-uses-base-64-encoding-of-user-pk


如果我错了,请纠正我,但是这个问题发生在django 1.6之前,对吗?不过,这个链接很好并且有很好的信息。 - Josh Brown
他可能正在使用测试版,或者注册应用程序已经预先更新了其URL模式。无论哪种方式,我认为这个解决方案对他都有效。 - Aidan

9

我的解决方案是将 registration\auth_urls.py 中定义的 urlpatterns 注释掉,并重新定义为 django.contrib.auth 中 urlpatterns 的副本。

以下是我进行更改后的 auth_urls.py:

"""
URL patterns for the views included in ``django.contrib.auth``.

Including these URLs (via the ``include()`` directive) will set up the
following patterns based at whatever URL prefix they are included
under:

* User login at ``login/``.

* User logout at ``logout/``.

* The two-step password change at ``password/change/`` and
  ``password/change/done/``.

* The four-step password reset at ``password/reset/``,
  ``password/reset/confirm/``, ``password/reset/complete/`` and
  ``password/reset/done/``.

The default registration backend already has an ``include()`` for
these URLs, so under the default setup it is not necessary to manually
include these views. Other backends may or may not include them;
consult a specific backend's documentation for details.

"""

from django.conf.urls.defaults import *

#from django.contrib.auth import views as auth_views

from django.contrib.auth import urls as auth_urls

urlpatterns = auth_urls.urlpatterns

'''
Commented out, this is what caused my problems:

urlpatterns = patterns('',
                       url(r'^login/$',
                           auth_views.login,
                           {'template_name': 'registration/login.html'},
                           name='auth_login'),
                       url(r'^logout/$',
                           auth_views.logout,
                           {'template_name': 'registration/logout.html'},
                           name='auth_logout'),
                       url(r'^password/change/$',
                           auth_views.password_change,
                           name='auth_password_change'),
                       url(r'^password/change/done/$',
                           auth_views.password_change_done,
                           name='auth_password_change_done'),
                       url(r'^password/reset/$',
                           auth_views.password_reset,
                           name='auth_password_reset'),
                       url(r'^password/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
                           auth_views.password_reset_confirm,
                           name='auth_password_reset_confirm'),
                       url(r'^password/reset/complete/$',
                           auth_views.password_reset_complete,
                           name='auth_password_reset_complete'),
                       url(r'^password/reset/done/$',
                           auth_views.password_reset_done,
                           name='auth_password_reset_done'),
) 
'''

你使用的是哪个Django版本?我遇到了同样的问题,但我的auth应用程序的文件结构似乎与你的有些不同。 - ductionist
我已经下载了最新的Django-nonrel。查看我的django__init__文件,我看到:VERSION = (1, 3, 0, 'final', 0),因此这一定是Django 1.3版本。 - mhl666

5

我需要将uidb36参数更改为uidb64,就像这样:

原文:

url(r'^password/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',

TO:

url(r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',

然后密码重置又开始正常工作了。


1

我猜您在urls.py中的password_reset_confirm url大致如下:

url(r'^accounts/password_reset/(?P[0-9A-Za-z]{1,13})-(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', password_reset_confirm, {'post_reset_redirect' : '/accounts/password_reset/complete/'},name="password_reset_confirm"),

并且你在password_reset_email.html中的链接看起来像这样: {{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb36=uid token=token %}

只需将两个地方的uib36更改为uib64,它就可以工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接