Электронное письмо с подтверждением регистрации Django 2 направляется на домашнюю страницу вместо страницы входа

#django #django-views #django-2.0

#django #django-просмотры #django-2.0

Вопрос:

Я настраиваю свое приложение Django 2.1 таким образом, чтобы при регистрации пользователя ему сначала отправлялось электронное письмо с подтверждением и ссылкой, по которой нужно нажать, чтобы активировать учетную запись.

До сих пор мне удалось настроить его (с помощью другого поста), и все работает вплоть до момента нажатия на электронное письмо с активацией.

Когда я копирую и вставляю ссылку в браузер, она перенаправляет меня на главную целевую страницу, а не на страницу входа в систему.

Кто-нибудь может просмотреть мои просмотры и посмотреть, не хватает ли чего-нибудь?

 def register_view(request):
    if request.method == 'POST':
        # Post request.
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.is_active = False
            user.save()

        mail_subject = 'Activate your account.'
        current_site = get_current_site(request)
        uid = urlsafe_base64_encode(force_bytes(user.pk)).decode()
        token = account_activation_token.make_token(user)
        activation_link = "{0}/?uid={1}amp;token{2}".format(current_site, uid, token)
        message = "Hello {0},n {1}".format(user.username, activation_link)
        to_email = form.cleaned_data.get('email')
        email = EmailMessage(mail_subject, message, to=[to_email])
        email.send()
        return HttpResponse('Please confirm your email address to complete the registration')

       else:
           # Get request.
           form = UserRegisterForm()
       return render(request, 'users/register.html', {'form': form})

def activate(request, uidb64, token):
        try:
            uid = urlsafe_base64_decode(uidb64).decode()
            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):
            # activate user and login:
            user.is_active = True
            user.save()
            messages.success(request, f'Your account has been created {username}. Login.')
            return render(request, 'users/login.html')
        else:
            return HttpResponse('Activation link is invalid!')
  

urls.py

 path('activate/<str:uid>/<str:token>',
    user_views.activate,
    name='activate'),
  

tokens.py

 class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
    def _make_hash_value(self, user, timestamp):
        return (
            six.text_type(user.pk)  
            six.text_type(timestamp)  
            six.text_type(user.is_active)
        )

account_activation_token = AccountActivationTokenGenerator()
  

Комментарии:

1. почему это {0} /?uid={1}amp;token{2}, а не token={2} ???

Ответ №1:

Я не смогу подтвердить, что вся функция регистрации работает, но чтобы ответить на ваш конкретный вопрос, ваш код создает activation_link, для которого установлено значение:

 activation_link = "{0}/?uid={1}amp;token{2}".format(current_site, uid, token)
  

что, если присмотреться, создает что-то вроде:

 http://example.com/?uid=....amp;token=....
  

но ваш путь в urls.py является

 path('activate/<str:uid>/<str:token>', user_views.activate, name='activate')
  

это означает, что ожидается что-то вроде

 http://example.com/activate/..../....
  

Поэтому исправление заключается в том, чтобы просто изменить activation_link на

 activation_link = "{0}/activate/{1}/{2}".format(current_site, uid, token)
  

Опять же, просто задавая конкретный вопрос, который вы задаете.

Если оставить в стороне ваш вопрос, вы можете захотеть ознакомиться с существующими пакетами, такими как django-registration или более полным пакетом, таким как django-allauth (который поддерживает процесс регистрации и вход в социальные сети, если потребуется позже)

Комментарии:

1. Спасибо за ваш чрезвычайно четкий ответ, просто блестящий. Да, я, очевидно, понимаю, почему это не сработало сейчас. Я изучу эти пакеты. Только один последний вопрос, я все еще не перехожу на страницу входа в систему, потому что получаю сообщение об ошибке, name 'uidb64' is not defined я предполагаю, из строки uid = urlsafe_base64_decode(uidb64).decode() , есть ли у вас какие-либо идеи, как это исправить?

2. Когда я меняю его на urlsafe_base64_decode(uidb64=uid).decode() , ошибка устраняется, но меня направляют на 'Activation link is invalid!'

3. Это совсем другой вопрос, возможно, для другого поста, но если у вас нет пользовательской модели пользователя, по умолчанию в качестве первичных ключей используются обычные целые числа, поэтому UUID не будет работать. Вам необходимо расшифровать UUID, чтобы извлечь фактический идентификатор пользователя. Как я уже сказал, это решаемая проблема, поэтому не нужно изобретать велосипед

4. Понял, я собираюсь использовать allauth, но в любом случае большое спасибо за вашу помощь.