Search code examples
djangodjango-email

Trying to get email activation to work, but it fails


Trying to get this tutorial to work in my app: https://medium.com/@frfahim/django-registration-with-confirmation-email-bb5da011e4ef

The 'uid' fails whether or not I include the .decode().

message = render_to_string('premium/activation_email.html', {'user':user,

 'token': account_activation_token.make_token(user),
 #this fails both with the .decode() and without
 'uid':urlsafe_base64_encode(force_bytes(user.pk)).decode(),
            })
mail_subject = 'Activate your membership account.'
send_mail(mail_subject, message,'info@mysite.com', [request.user.email])

These are the two errors:

Reverse for 'activate' not found. 'activate' is not a valid view function or pattern name

Then if I add .decode():

str object has no attribute decode()

here is my urls.py with the activate tag:

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

my activate view is exactly the same as the one in the tutorial


Solution

  • Since Django >2.2, urlsafe_base64_encode will return string instead of bytestring so you don't have to call .decode() after urlsafe_base64_encode anymore.

    Changed in Django 2.2: In older versions, it returns a bytestring instead of a string.

    Follow the guideline which you embedded on your question, the issue Reverse for 'activate' not found comes from this:

    {% autoescape off %}
    Hi {{ user.username }},
    Please click on the link to confirm your registration,
    http://{{ domain }}{% url 'activate' uidb64=uid token=token %}
    {% endautoescape %}
    

    There are 2 cases that might lead to this issue:

    1. Your path:
    path('activate/<uidb64>/<token>/', views.activate, 'activate'),
    

    you should named your view by this:

    path('activate/<uidb64>/<token>/', views.activate, name='activate'),
    
    1. If your view is stay on site level (inside django application urls, not in ROOT_URLS) then you might need to add app_name = 'your_app_name' on top of your urlpatterns inside urls.py. And then inside your mail template:
    {% autoescape off %}
    Hi {{ user.username }},
    Please click on the link to confirm your registration,
    http://{{ domain }}{% url 'your_app_name:activate' uidb64=uid token=token %}
    {% endautoescape %}
    

    Hope that helps!