[Django]-NoReverseMatch with keyword argument uidb64 with Django 2.0

56👍

In Django 2.0 and 2.1 you should call decode() after base64 encoding the uid, to convert it to a string:

message = render_to_string('acc_active_email.html', {
    'user': user,
    'domain': current_site.domain,
    'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
    'token': account_activation_token.make_token(user),
})

See the note in the Django 2.0 release notes for more info.

In Django 2.2+, urlsafe_base64_encode returns a string, so there is no need to decode.

message = render_to_string('acc_active_email.html', {
    'user': user,
    'domain': current_site.domain,
    'uid': urlsafe_base64_encode(force_bytes(user.pk)),
    'token': account_activation_token.make_token(user),
})

It should be possible to write code that is compatible with Django <= 1.11, 2.0-2.1, and 2.2+, by using force_text. Note the following is untested.

from django.utils.encoding import force_text

message = render_to_string('acc_active_email.html', {
    'user': user,
    'domain': current_site.domain,
    'uid': force_text(urlsafe_base64_encode(force_bytes(user.pk))),
    'token': account_activation_token.make_token(user),
})

You can drop the force_text and use the second code snippet once you drop support for Django < 2.2.

6👍

For newer versions of Django, you can use the slug syntax. For example:

path(
    'activate/<slug:uidb64>/<slug:token>/',
    views.activate_account, 
    name='activate'
)

1👍

In my case, I configured my template (acc_active_email.html) to be like this:

{% autoescape off %}

Hello {{ name }}!

Please confirm your email by clicking on the following link.

http://{{ domain }}/activate/{{ uid }}/{{ token }}

{% endautoescape %}

Next I included in the urls.py from my app:

path('activate/<uidb64>/<token>/', views.activate, name='activate')

I don’t know if it’s the best way, but it solved my problems. However, I used django 4.1 version, so may be it doesn’t work well for you.

0👍

Maybe its stupid since the URL is not dynamic but it worked…

path('activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', views.activate, name='activate'),

Leave a comment