#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, но в любом случае большое спасибо за вашу помощь.