web-dev-qa-db-ja.com

キーワード引数uidb64を使用したNoReverseMatch 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ファイル

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

17
r2546971

Django 2.0および2.1では、uidをbase64エンコードした後にdecode()を呼び出して、それを文字列に変換する必要があります。

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

_force_text_を使用して、Django <1.11、2.0-2.1、および2.2+と互換性のあるコードを記述できるはずです。以下はテストされていないことに注意してください。

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

Django <2.2のサポートを削除したら、_force_text_を削除して2番目のコードスニペットを使用できます。

49
Alasdair