Home > front end >  Django: "Cannot resolve keyword 'email' into field. Choices are: created_at, expires_
Django: "Cannot resolve keyword 'email' into field. Choices are: created_at, expires_

Time:09-12

I'm trying to validate an OTP that was sent to the user when registering i have a separate model for otp which has an OneToOne relation with the user

Otp Model

class Verify(models.Model):
user = models.ForeignKey(
    User, on_delete=models.CASCADE, related_name="userverify", blank=False, 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.TimeField(null=True)

the VerifySerializer: I don't specify the model because i only need it to check the validity of the input, although i think this might be the problem

class VerifySerializerBase(serializers.Serializer):
   email = serializers.EmailField()
   otp = serializers.CharField()

the Verify_Email view takes an email and otp value to validate the email

How I'm trying to verify the otp

class Verify_Email(APIView):
    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.filter(email=email, otp=otp)
                user = User.objects.filter(email=email)

                if not user[0].exists():
                    return Response({
                        'message': "A user with this email was not found"
                    }, status=status.HTTP_400_BAD_REQUEST)
                elif user[0].is_active:
                    return Response({
                        'message': "This email has already been verified"
                    }, status=status.HTTP_400_BAD_REQUEST)

                elif verify[0].exists():
                    if verify[0].expires_at >= datetime.now():
                        return Response({
                            'message': "This OTP has expired, please request another one"
                        }, status=status.HTTP_400_BAD_REQUEST)
                    elif verify[0].otp != otp:
                        return Response({
                            'message': "This OTP is invalid"
                        }, status=status.HTTP_400_BAD_REQUEST)
                    else:
                        verify[0].delete()
                        user[0].is_active = True
                        user[0].save()
                        return Response({
                            'message': "Email has been verified"
                        }, status=status.HTTP_200_OK)
                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)

and when testing i get

"Cannot resolve keyword 'email' into field. Choices are: created_at, expires_at, id, otp, user, user_id"

from what I understand i think it's telling me that I'm checking for fields that are not in the OTP model fields but I don't think I'm doing that??

CodePudding user response:

The error relates to the models, not the serializer. This line implies that a Verify model has a field email, because you're building a query on that field:

verify = Verify.objects.filter(email=email, otp=otp)

Perhaps you meant to query by user instead, which involves swapping with the following line like so:

user = User.objects.get(email=email)
verify = Verify.objects.filter(user=user, otp=otp)
  • Related