I'm using Django-nonrel with registration app. Things seem to be working fine, except when I try to reset my password. When clicking on reset-password link sent to me in email, Django produces error message:
password_reset_confirm() got an unexpected keyword argument 'uidb36'
My question: has anybody seen it and knows what's the cure?
EDIT:
The problem is caused by registration\auth_urls.py - they duplicate entries in django\contrib\auth\urls.py, circumwenting patched version of the file in Django-nonrel.
Any ideas why is it there and can I actually remove it or fix it otherwise?
Django 1.6 uses base 64 encoding for the User's ID instead of base 36 encoding.
If you have any custom password reset URLs, you will need to update them by replacing uidb36 with uidb64 and the dash that follows that pattern with a slash. Also add "_", "\" and "-" to the list of characters that may match the uidb64 pattern.
For example this line in urls.py in 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'),
Will need to be changed to this in 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'),
Here is the official changelog which details the change: https://docs.djangoproject.com/en/1.6/releases/1.6/#django-contrib-auth-password-reset-uses-base-64-encoding-of-user-pk
My solution was to comment out urlpatterns defined in registration\auth_urls.py, and redefine them as a copy of urlpatterns defined in django.contrib.auth.
Here's my auth_urls.py after the change:
"""
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'),
)
'''
I just had to change the uidb36
argument to uidb64
, like so:
FROM:
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>.+)/$',
Then password resets began working again.
I guess your password_reset_confirm url in urls.py looks something similar to
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"),
and your link in password_reset_email.html looks like {{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb36=uid token=token %}
Just change uib36 to uib64 both the places,it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With