尝试从模板创建电子邮件时,使用正则表达式的NoReverseMatch以url作为参数

时间:2018-02-15 08:50:17

标签: python regex django

我试图使用gmail向gmail发送来自Django的电子邮件。使用send_mail

@method_decorator(csrf_exempt, name='dispatch')
class AuthenticationView(View):

    @classmethod
    def send_email(cls, request, user):
        current_site = get_current_site(request)
        mail_subject = 'Activate your Poros account.'
        message = render_to_string('email_verification.html', {
            'user': user,
            'domain': current_site.domain,
            'uid': urlsafe_base64_encode(force_bytes(user.pk)),
            'token': account_activation_token.make_token(user),
        })
        to_email = user.email
        email = EmailMessage(
            mail_subject, message, to=[to_email]
        )
        email.send()

然后我为我的应用设置了url模式,如下所示:

from django.conf.urls import url
from django.urls import path

from .views.activation import activate

from .views import UserView, ProfileView, AuthenticationView

urlpatterns = [
    path('users/', UserView.as_view()),
    path('auth/', AuthenticationView.as_view()),
    path('profiles/<str:pk>/', ProfileView.as_view()),
    url(r'activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
        activate, name='activate'),
]

并将包含在项目网址中:

from django.conf.urls import include
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('accounts.urls'),)
]

并且activate视图来自activate(),如下所示:

from django.http import HttpResponse

from django.contrib.auth import login

from django.utils.encoding import force_text
from django.utils.http import urlsafe_base64_decode
from accounts.utilities import account_activation_token
from django.contrib.auth.models import User


def activate(request, uidb64, token):
    try:
        uid = force_text(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except(TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.save()
        login(request, user)
        return HttpResponse('Thank you for your email confirmation. Now you can login your account.')
    else:
        return HttpResponse('Activation link is invalid!')

当我尝试从activate模板中的网址名称email_verification获取网址时出现错误:

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

这个问题在调用send_mail时返回错误。它给了我这个:

NoReverseMatch at /accounts/users/ Reverse for 'activate' with keyword
arguments '{'uidb64': b'ZDRkMTBkODBiNzc3NDFlZWE4NzczMjRmNTM1MDg3M2M',
'token': '4tq-2981c84990bfedab3525'}' not found. 1 pattern(s) tried:
['accounts\\/activate/(?P<uidb64>[0-9A-Za-z_\\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$']

我在模板中使用的网址似乎与我的网址模式不匹配。有没有办法使用正常路径来防止超混淆 - 正则表达式匹配?或者任何人都有更好的方法吗?

1 个答案:

答案 0 :(得分:4)

问题不在于您的正则表达式,而是您将字节串传递给模板而不是普通字符串。您需要在您的uid上致电decode()

'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),