Проверка электронной почты в 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"
        ]
Вернуться на верх