Проверка электронной почты в django python
Я пытаюсь выполнить проверку электронной почты в django, все работает корректно, но если пользователь создает учетную запись с чужой электронной почтой и если пользователь не подтвердит электронную почту, владелец этого электронного письма не сможет зарегистрироваться, потому что учетная запись уже зарегистрирована, а is_active имеет значение False. Вот мой views.py с регистрационной формой "'
from django.shortcuts import render, redirect
from django.http.request import HttpRequest
from django.http import JsonResponse
from .forms import UserRegisterForm, UserLoginForm
from .models import User
from .tokens import accound_activate_token
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.utils.encoding import force_bytes, force_str
from django.core.mail import send_mail
# from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate, login, logout
def send_email_validation(request: HttpRequest, user: User, form: UserRegisterForm):
current_site = get_current_site(request)
mail_subject = "Activate your account"
message = render_to_string(
"users/emails/email_activation.html",
{
"user": user,
"domain": current_site.domain,
"uid": urlsafe_base64_encode(force_bytes(user.pk)),
'token': accound_activate_token.make_token(user)
}
)
from_email = "xxx"
to_email = form.cleaned_data["email"]
send_mail(
mail_subject, message, from_email,
[to_email]
)
def register_page(request: HttpRequest):
if request.method == "GET":
reg_form = UserRegisterForm()
if request.method == "POST":
reg_form = UserRegisterForm(request.POST)
# create user and redirect to login
if reg_form.is_valid():
user: User = reg_form.save(commit=False)
user.is_active = False
user.save()
# sending email for validation
send_email_validation(request, user, reg_form)
return redirect("users_login")
context = {
"form": reg_form
}
return render(request, "users/register.html", context)
def activate_email(reqest: HttpRequest, uidb64, token):
try:
uid = force_str(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user and accound_activate_token.check_token(user, token):
user.is_active = True
user.save()
return redirect("main_page")
'''
tokens.py "'
from django.contrib.auth.tokens import PasswordResetTokenGenerator
class AccoundActivationTokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return f"{user.pk}{timestamp}{user.is_active}"
accound_activate_token = AccoundActivationTokenGenerator()
'''
Я думаю, что мне нужно сохранить пользователя только после успешной проверки электронной почты, но я не знаю, будет ли это правильно
Исходя из описанного сценария, одним из эффективных подходов является добавление поля created_at в поле User model для отслеживания времени создания учетной записи. После регистрации пользователя должно быть отправлено электронное письмо с подтверждением, и учетная запись должна оставаться неактивной до тех пор, пока электронное письмо не будет подтверждено. Если пользователь не подтвердит свою электронную почту в течение определенного периода времени (например, 1 часа), непроверенная учетная запись может быть автоматически удалена. Это позволяет повторно использовать тот же адрес электронной почты для регистрации по истечении срока действия, гарантируя, что законные пользователи не будут заблокированы из-за неактивных, непроверенных учетных записей.
Кажется, я понял, мне просто нужно проверить пользователя при регистрации и удалить его, если учетная запись не активна
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(
label=_("Email"),
max_length=100,
required=True,
)
first_name = forms.CharField(
label=_("First Name"),
max_length=100,
required=True,
)
last_name = forms.CharField(
label=_("Last Name"),
max_length=100,
required=True,
)
def __init__(self, *args, **kwargs):
super(UserRegisterForm, self).__init__(*args, **kwargs)
# clear hepl texts
for field in self.fields.values():
field.help_text = None
def clean_email(self):
email = self.cleaned_data['email']
try:
# get and delete user with not active account
user = User.objects.get(email=email)
if not user.is_active:
user.delete()
return email
# user exists and acount is active
raise forms.ValidationError(_("Email already exists"))
except User.DoesNotExist:
return email
class Meta:
model = User
fields = [
"email",
"first_name",
"last_name",
"password1",
"password2"
]