NoReverseMatch 与关键字参数 uidb64 与 Django 2.0

新手上路,请多包涵

我不明白为什么我的代码不起作用。在它工作之前,但是现在,当我运行服务器并进行测试时,代码不起作用。

当用户注册时,我会向他发送激活电子邮件,如下所示:

 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 %}

和我的网址文件

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

但我有这个错误:

 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})/$']

突出显示这一行 http://{{ domain }}{% url 'activate' uidb64=uid token=token %}

原文由 r2546971 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 582
2 个回答

在 Django 2.0 和 2.1 中,你应该调用 decode() 在对 uid 进行 base64 编码之后,将其转换为字符串:

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

有关详细信息,请参阅 Django 2.0 发行说明 中的说明。

在 Django 2.2+ 中, urlsafe_base64_encode 返回一个字符串,所以不需要解码。

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

应该可以编写与 Django <= 1.11、2.0-2.1 和 2.2+ 兼容的代码,方法是使用 force_text 。请注意以下内容未经测试。

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

您可以删除 force_text 并在您放弃对 Django < 2.2 的支持后使用第二个代码片段。

原文由 Alasdair 发布,翻译遵循 CC BY-SA 4.0 许可协议

对于较新版本的 Django,您可以使用 slug 语法。例如:

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

原文由 lehoang 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题