Django-nonrel + проблема с регистрацией Django: неожиданный аргумент ключевого слова «uidb36» при сбросе пароля

Я использую Django-nonrel с регистрация приложение. Кажется, все работает нормально, за исключением случаев, когда я пытаюсь сбросить свой пароль. При нажатии на ссылку сброса пароля, отправленную мне по электронной почте, Django выдает сообщение об ошибке:

password_reset_confirm() got an unexpected keyword argument 'uidb36'

Мой вопрос: кто-нибудь видел это и знает, как лечить?

ИЗМЕНИТЬ:

Проблема связана с Registration\auth_urls.py - они дублируют записи в django\contrib\auth\urls.py, обходя пропатченную версию файла в Django-nonrel.

Любые идеи, почему он там, и могу ли я удалить его или исправить иначе?


person mhl666    schedule 12.06.2011    source источник


Ответы (4)


Django 1.6 использует кодировку base 64 для идентификатора пользователя вместо кодировки base 36.

Если у вас есть какие-либо собственные URL-адреса для сброса пароля, вам необходимо обновить их, заменив uidb36 на uidb64 и тире, следующее за этим шаблоном, на косую черту. Также добавьте «_», «\» и «-» в список символов, которые могут соответствовать шаблону uidb64.

Например, эта строка в urls.py в Django 1.5-:

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-кодировка-пользователя-pk

person Aidan    schedule 03.12.2013
comment
поправьте меня, если я ошибаюсь, но этот вопрос был задолго до django 1.6, верно? Тем не менее, хорошая ссылка с хорошей информацией - person Josh Brown; 29.01.2014
comment
Возможно, он использовал бета-версию или приложение для регистрации заранее обновило свои шаблоны URL. В любом случае, я думаю, что решение сработает для него. - person Aidan; 30.01.2014

Мое решение состояло в том, чтобы закомментировать шаблоны URL, определенные в Registration\auth_urls.py, и переопределить их как копию шаблонов URL, определенных в django.contrib.auth.

Вот мой 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'),
) 
'''
person mhl666    schedule 13.06.2011
comment
какую версию Django вы используете? У меня та же проблема, но кажется, что файловая структура моего приложения аутентификации немного отличается от вашей. - person ductionist; 15.06.2011
comment
Я скачал последнюю версию Django-nonrel. Глядя на мой django_init_, я вижу: VERSION = (1, 3, 0, 'final', 0), так что это должно быть Django 1.3. - person mhl666; 15.06.2011

Мне просто нужно было изменить аргумент 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>.+)/$',

Затем сброс пароля снова начал работать.

person Matt Williamson    schedule 21.12.2011

Я предполагаю, что ваш URL-адрес password_reset_confirm в urls.py выглядит примерно так:

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 выглядит как {{ протокол }}://{{ домен }}{% url 'password_reset_confirm' uidb36=uid token=token %}

Просто измените uib36 на uib64 в обоих местах, это работает.

person MANOJ REDDY    schedule 16.02.2017