0

I'm just a beginner, so i got some questions making my first project. I've got code in views:

def signup(request):
if request.method == 'POST':
    form = SignupForm(request.POST)
    if form.is_valid():
        user = form.save(commit=False)
        user.is_active = False
        user.save()
        current_site = get_current_site(request)
        mail_subject = 'Активация'
        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),
        })
        print(message) # здесь я смотрю какое сообщение отправляю

        to_email = form.cleaned_data.get('email')
        email = EmailMessage(
                    mail_subject, message, to=[to_email]
        )
        email.send()
        return HttpResponse('Пожалуйста, подтвердите адрес электронной почты')
else:
    form = SignupForm()
return render(request, 'signup.html', {'form': form})


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 redirect('home')
        return HttpResponse('Thank you for your email confirmation. Now you can login your account.')
    else:
        return HttpResponse('Activation link is invalid!')

This code is from urls:

from . import views
from django.urls import path

urlpatterns = [
    path('', views.signup, name='signup'),
    path('activate/?P<uidb64>[0-9A-Za-z_\-]+/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
        views.activate, name='activate'),
]

The problem is that i always get invalid URL in my email. I think it is about new 'path' function, which may be used is

<int:uidb64>

but not really sure. Thank for your help!

MD. Khairul Basar
  • 4,976
  • 14
  • 41
  • 59
D. Make
  • 579
  • 2
  • 6
  • 23

1 Answers1

8

You can't use regexes like [0-9A-Za-z_\-]+ when you use path(). If you want to use regexes, then use re_path (which works the same as url() from older versions of Django).

When you use path(), you can use one of the built-in path converters. You can't use <int:uidb64>, because uidb can contain A-Za-z, hyphens, and underscores, not just digits.

For your uidb64 and token, I think slug is the most suitable of the path converters included in Django.

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

This will match slugs and tokens which your regex wouldn't allow, but this isn't a problem as long as your check_token method returns False for these invalid values and does not raise an error.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • Thank for your reply, but now i get NoReverseMatch at /signup/. Can you please give an advice how to solve this problem? – D. Make Dec 14 '17 at 12:44
  • Maybe this is about my html file: {% autoescape off %} Здравствуйте {{ user.username }}, Пожалуйста нажмите на ссылку, чтобы активировать аккаунт: http://{{ domain }}{% url 'activate' =uid =token %} {% endautoescape %} – D. Make Dec 14 '17 at 13:12
  • You don't use the path converters syntax in the url tag, just the variable name: `{% url 'activate' uidb64=uid token=token %}`. Or you can use positional arguments: `{% url 'activate' uid token %}`. – Alasdair Dec 14 '17 at 13:25
  • Still got a error with that 'activate'. Reverse for 'activate' with arguments '(b'NjI', '4rz-742abd4c7bd36c6edcd0')' not found. Using both of your variants, it comes much more clear to me, but i still can't get why it dont work. Do i understand right that 'activate' is supposed to be just a word inside that URL? – D. Make Dec 14 '17 at 13:35
  • You use `'activate'` because you are trying to reverse the pattern with `name='activate'`. The problem is that `b'Njl'` is bytes. See this question: https://stackoverflow.com/questions/47177696/noreversematch-django-template-url. If you're still stuck, please ask a new question because this is a separate issue. – Alasdair Dec 14 '17 at 13:44
  • Appreciate your comments so much! It worked. That was all about that decode, everithing becomes so much clearer! Thank you! – D. Make Dec 14 '17 at 13:56