问题
I can\'t understand why my code doesn\'t work. Before it worked, but now, when I run the server and test, the code does not work.
When the user is registering, I send him activation email, like this:
def send_activation_email(serializer, request, user):
current_site = get_current_site(request)
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),
})
mail_subject = \'Activate your blog account.\'
to_email = serializer.data[\'email\']
email = EmailMessage(mail_subject, message, to=[to_email])
email.send()
acc_active_email.html
{% autoescape off %}
Hi {{ user.username }},
Please click on the link to confirm your registration,
http://{{ domain }}{% url \'activate\' uidb64=uid token=token %}
{% endautoescape %}
and my url file
.
.
url(r\'^activate/(?P<uidb64>[0-9A-Za-z_\\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$\',
views.activate_account, name=\'activate\'),
.
.
but I have this error:
Exception Type: NoReverseMatch
Exception Value:
Reverse for \'activate\' with keyword arguments \'{\'uidb64\': b\'NDM\', \'token\': \'4qz-8f770502bd8b02786da9\'}\' not found. 1 pattern(s) tried: [\'activate/(?P<uidb64>[0-9A-Za-z_\\\\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$\']
highlights this line http://{{ domain }}{% url \'activate\' uidb64=uid token=token %}
回答1:
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.
来源:https://stackoverflow.com/questions/47177696/noreversematch-with-keyword-argument-uidb64-with-django-2-0