NoReverseMatch with keyword argument uidb64 with Django 2.0 NoReverseMatch with keyword argument uidb64 with Django 2.0 python python

NoReverseMatch with keyword argument uidb64 with Django 2.0


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_textmessage = 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.


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

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


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'),