NoReverseMatch 与关键字参数 uidb64 与 Django 2.0 [英] NoReverseMatch with keyword argument uidb64 with Django 2.0

查看:35
本文介绍了NoReverseMatch 与关键字参数 uidb64 与 Django 2.0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

def send_activation_email(serializer, request, user):current_site = get_current_site(请求)message = render_to_string('acc_active_email.html', {'用户':用户,域":current_site.domain,'uid': urlsafe_base64_encode(force_bytes(user.pk)),'token': account_activation_token.make_token(user),})mail_subject = '激活您的博客帐户.'to_email = serializer.data['email']email = EmailMessage(mail_subject, message, to=[to_email])电子邮件.发送()

acc_active_email.html

{% autoescape off %}嗨{{ user.username }},请点击链接确认您的注册,http://{{ 域 }}{% url '激活' uidb64=uid token=token %}{% endautoescape %}

和我的网址文件

<预><代码>..url(r'^activate/(?P[0-9A-Za-z_-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',views.activate_account, name='activate'),..

但我有这个错误:

异常类型:NoReverseMatch异常值:反向使用关键字参数 '{'uidb64': b'NDM', 'token': '4qz-8f770502bd8b02786da9'}' 未找到.尝试了 1 个模式:['activate/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$']

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

解决方案

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

message = render_to_string('acc_active_email.html', {'用户':用户,域":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', {'用户':用户,域":current_site.domain,'uid': urlsafe_base64_encode(force_bytes(user.pk)),'token': account_activation_token.make_token(user),})

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

from django.utils.encoding import force_textmessage = render_to_string('acc_active_email.html', {'用户':用户,域":current_site.domain,'uid': force_text(urlsafe_base64_encode(force_bytes(user.pk))),'token': account_activation_token.make_token(user),})

一旦您放弃对 Django 的支持,您就可以放弃 force_text 并使用第二个代码片段2.2.

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

解决方案

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.

这篇关于NoReverseMatch 与关键字参数 uidb64 与 Django 2.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆