Я работал над созданием системы сброса пароля на своем сайте django

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

определить пароль_reset_request(запрос): если request.method == 'POST': электронная почта = request.POST.get('электронная почта') попробуйте: user = get_user_model().objects.get(email=электронная почта)

        # Generate reset token and expiry
        profile, created = UserProfile.objects.get_or_create(user=user)
        profile.generate_reset_token()

        # Prepare the email context with the reset token
        context = {
            'user': user,
            'reset_token': profile.reset_token,  # Send the reset token in the email
        }

        # Render email templates
        email_html = render_to_string('password_reset_email.html', context)
        email_plain = strip_tags(email_html)

        # Mailgun API setup
        mailgun_url = f"https://api.mailgun.net/v4/{MAILGUN_DOMAIN_NAME}/messages"
        mailgun_auth = ("api", MAILGUN_API_KEY)
        mailgun_data = {
            "from":DEFAULT_FROM_EMAIL,
            "to": user.email,
            "subject": "Password Reset Request",
            "text": email_plain,
            "html": email_html
        }

        # Send email via Mailgun API
        try:
            response = requests.post(mailgun_url, auth=mailgun_auth, data=mailgun_data, verify=False)

            if response.status_code == 200:
                messages.success(request, "A password reset token has been sent to your email.")
            else:
                messages.warning(request, "Password reset requested, but there was an issue sending the email.")

        except requests.exceptions.RequestException as e:
            messages.warning(request, f"Password reset requested, but we couldn't send the email: {str(e)}")

        return redirect('password_reset_verify')

    except get_user_model().DoesNotExist:
        messages.error(request, "Email address not found.")

return render(request, 'password_reset_request.html')

определите пароль для повторной проверки(запрос): если request.method == 'POST': токен = request.POST.get('токен') # Предполагается, что пользователь вводит токен здесь , если токен: пробовать: # Найдите профиль пользователя, используя токен profile = UserProfile.objects.get(reset_token=токен)

            if profile.is_reset_token_valid():
                # Create the uidb64 from user ID (convert user ID to string before encoding)
                uidb64 = urlsafe_base64_encode(str(profile.user.pk).encode())

                # Use the reset token
                token = profile.reset_token
                
                # Redirect to the password reset confirmation page with parameters
                return redirect('password_reset_confirm', uidb64=uidb64, token=token)
            else:
                messages.error(request, "The reset token is invalid or has expired.")
        except UserProfile.DoesNotExist:
            messages.error(request, "Invalid token.")
    else:
        messages.error(request, "No token provided.")

return render(request, 'password_reset_verify.html')

из файла .forms импортируем форму ввода пароля

определение пароля_reset_confirm(запрос, uidb64, токен): пробовать: # Расшифруем uidb64 и получим uid пользователя = urlsafe_base64_decode(uidb64).расшифруем('utf-8') user = get_user_model().objects.get(pk=uid)

    # Check if the token is valid for this user
    profile = UserProfile.objects.get(user=user)
    if not profile.is_reset_token_valid() or profile.reset_token != token:
        messages.error(request, "The reset token is invalid or has expired.")
        return redirect('password_reset_request')  # Redirect to the reset request page

    # If the token is valid, proceed with the password reset
    if request.method == 'POST':
        form = PasswordResetForm(user=user, data=request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, "Your password has been reset successfully.")
            return redirect('login')  # Redirect to the login page after successful password reset
    else:
        form = PasswordResetForm(user=user)
except (TypeError, ValueError, OverflowError, UserProfile.DoesNotExist):
    messages.error(request, "Invalid token or user.")
    return redirect('password_reset_request')

return render(request, 'password_reset_confirm.html', {'form': form})

из django.contrib.auth.forms импортируем SetPasswordForm

класс PasswordResetForm(SetPasswordForm): """Пользовательская форма сброса пароля для обработки логики сброса пароля."""

def clean(self):
    cleaned_data = super().clean()
    password = cleaned_data.get("new_password1")
    confirm_password = cleaned_data.get("new_password2")
    
    if password != confirm_password:
        raise forms.ValidationError("The two password fields must match.")
    
    return cleaned_data

импортировать случайную строку импорта из django.utils импортировать часовой пояс

Пользователь = get_user_model()

класс UserProfile(models.Model): пользователь = models.OneToOneField(Пользователь, on_delete=models.КАСКАД, имя_связи="профиль")

# Reset token fields
reset_token = models.CharField(max_length=6, null=True, blank=True)
reset_token_expiry = models.DateTimeField(null=True, blank=True)
SPECIALTY_CHOICES = [
    ('Beauticians', 'Beauticians'),
    ('Hairdressers', 'Hairdressers'),
    ('Nail Technicians', 'Nail Technicians'),
    ('Tattoo Artists', 'Tattoo Artists'),
    ('Dog Groomers', 'Dog Groomers'),
    ('Aesthetic Practitioners', 'Aesthetic Practitioners'),
    ('Sports Therapists', 'Sports Therapists'),
    ('Physiotherapists', 'Physiotherapists'),
    ('Chiropractors', 'Chiropractors'),
    ('Semi-Permanent Makeup Artists', 'Semi-Permanent Makeup Artists'),
]

user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
specialty = models.CharField(max_length=100, choices=SPECIALTY_CHOICES, blank=True, null=True) 

def __str__(self):
    return f"Profile for {self.user.username} ({self.get_specialty_display()})"

def generate_reset_token(self):
    """Generate a random 6-digit numeric token and ensure uniqueness."""
    self.reset_token = ''.join(random.choices(string.digits, k=6))  # Using only digits for simplicity
    self.reset_token_expiry = timezone.now() + timedelta(hours=1)  # Token expires in 1 hour
    self.save()

def is_reset_token_valid(self):
    """Check if the reset token is still valid."""
    return self.reset_token and self.reset_token_expiry and timezone.now() < self.reset_token_expiry

def clear_reset_token(self):
    """Clears the reset token after use."""
    self.reset_token = None
    self.reset_token_expiry = None
    self.save()
Вернуться на верх