Django: ошибка при попытке проверки электронной почты otp
Я отправляю электронное письмо пользователю при регистрации и получаю otp вместе с письмом, у меня есть отдельная модель проверки, которая выглядит как показано ниже, ошибка, с которой я сталкиваюсь, это {"message": "This OTP is invalid"}
которая имеет отношение к миру кода в представлении verifyEmail (ниже)
class Verify(models.Model):
email = models.EmailField(
_("Email"), max_length=254, unique=True, default=None, blank=True, null=True)
otp = IntegerRangeField(
min_value=111111, max_value=999999, blank=True, null=True)
created_at = models.DateTimeField(
_("created at"), auto_now=False, auto_now_add=True, blank=False)
expires_at = models.DateTimeField(null=True)
def __str__(self) -> str:
return self.email
как я отправляю письмо
def send_opt_email(email, firstname, lastname):
otp = random.randint(100000, 999999)
subject = 'Email verification'
message = 'Email verification'
html_message = loader.render_to_string(
'email_verify.html',
{
'firstname': firstname,
'lastname': lastname,
'otp': otp,
}
)
email_from = settings.EMAIL_HOST_USER
send_mail(subject, message, email_from, [
email], fail_silently=True, html_message=html_message)
otp = Verify.objects.create(
email=email,
otp=otp,
created_at=datetime.now(),
expires_at=datetime.now() + timedelta(minutes=30)
)
otp.save()
это представление я использую для проверки otp
class Verify_Email(APIView):
"""
Verify registered emails
"""
def post(self, request):
try:
data = request.data
serializer = VerifySerializerBase(data=data)
if serializer.is_valid():
email = serializer.data['email']
otp = serializer.data['otp']
verify = Verify.objects.get(email=email)
user = User.objects.get(email=email)
try:
if user.is_active:
return Response({
'message': "This email has already been verified"
}, status=status.HTTP_400_BAD_REQUEST)
elif verify:
print(verify.email)
print(verify.otp)
print(verify.created_at)
print(verify.expires_at)
#prints everything as expected
now = timezone.now()
if verify.otp != otp:
return Response({
'message': "This OTP is invalid"
}, status=status.HTTP_400_BAD_REQUEST)
elif verify.expires_at < now:
return Response({
'message': "This OTP has expired, please request another one"
}, status=status.HTTP_400_BAD_REQUEST)
verify.delete()
user.is_active = True
user.save()
return Response({
'message': "Email has been verified"
}, status=status.HTTP_200_OK)
except User.DoesNotExist:
return Response({"message": "User was not found"}, status=status.HTTP_404_NOT_FOUND)
return Response({
'message': "Something is wrong"
}, status=status.HTTP_400_BAD_REQUEST)
return Response({
'message': "Something is wrong"
}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
return Response(str(e), status=status.HTTP_404_NOT_FOUND, template_name=None, content_type=None)
Я не думаю, что представление Verify_Email является хорошей реализацией, и любые улучшения будут оценены по достоинству
Пробовали ли вы приводить тип переменной? (т.е. if int(verify.otp) != int(otp):
)
Кроме того, уверены ли вы на 100%, что verify.otp == otp
? Я вижу, что вы печатаете verify.otp
, но не otp
. Каковы оба результата?
Вы получили то, что искали в ответе Сорена Рифе, и я просто почистил ваш код. (однако он может вам не понравиться)
from django.shortcuts import get_object_or_404
from rest_framework.exceptions import ValidationError
class Verify_Email(APIView):
def post(self, request):
serializer = VerifySerializerBase(data=request.data)
if not serializer.is_valid():
raise ValidationError(
"Something is wrong"
)
email = serializer.data['email']
otp = serializer.data['otp']
user = get_object_or_404(User, email=email)
if user.is_active:
raise ValidationError(
"This email has already been verified",
)
verify = get_object_or_404(Verify, email=email)
if int(verify.otp) != int(otp):
raise ValidationError(
"This OTP is invalid"
)
if verify.expired:
raise ValidationError(
"This OTP has expired, please request another one"
)
verify.delete()
user.is_active = True
user.save()
return Response(
{'message': "Email has been verified"},
status=status.HTTP_200_OK
)
from datetime import datetime
class Verify(models.Model):
email = models.EmailField(
_("Email"), max_length=254, unique=True, default=None, blank=True, null=True)
otp = IntegerRangeField(
min_value=111111, max_value=999999, blank=True, null=True)
created_at = models.DateTimeField(
_("created at"), auto_now_add=True)
expires_at = models.DateTimeField(null=True)
def __str__(self) -> str:
return self.email
@property
def expired(self):
return self.expires_at < datetime.now()