Django注册OTP验证报错:无法将'email'解析为模型字段
问题排查与解决
错误原因
报错提示Cannot resolve keyword 'email' into field,是因为你在视图中直接尝试用email作为查询条件过滤Verify模型,但Verify表本身并没有email字段——email是关联的User模型的字段。
解决思路与代码示例
正确的验证逻辑应该是:先通过传入的email找到对应的用户,再通过用户关联查询对应的Verify记录,同时匹配OTP并验证是否过期。
以下是修正后的视图示例:
from django.contrib.auth.models import User from django.utils import timezone from datetime import datetime from rest_framework.response import Response from rest_framework.views import APIView from .models import Verify from .serializers import VerifySerializerBase class Verify_Email(APIView): def post(self, request): serializer = VerifySerializerBase(data=request.data) if serializer.is_valid(): email = serializer.validated_data['email'] otp = serializer.validated_data['otp'] try: # 第一步:通过邮箱找到对应的用户 user = User.objects.get(email=email) # 第二步:通过用户关联查询匹配的OTP记录 verify_record = Verify.objects.get(user=user, otp=otp) # 第三步:验证OTP是否过期(结合created_at和expires_at) # 因为expires_at是TimeField,需要和created_at的日期组合成完整时间 expire_datetime = timezone.make_aware( datetime.combine(verify_record.created_at.date(), verify_record.expires_at) ) if timezone.now() > expire_datetime: return Response({"error": "OTP已过期"}, status=400) return Response({"message": "OTP验证成功"}, status=200) except User.DoesNotExist: return Response({"error": "该邮箱未注册"}, status=404) except Verify.DoesNotExist: return Response({"error": "OTP无效或与邮箱不匹配"}, status=400) return Response(serializer.errors, status=400)
关键注意点
- 不要直接用关联模型的字段作为当前模型的查询条件,必须通过外键关联查询(比如
user=user)。 - 必须处理
User.DoesNotExist和Verify.DoesNotExist两种异常,分别返回对应的错误提示。 - 一定要加上OTP过期验证,避免无效的旧OTP被重复使用,提升安全性。
内容的提问来源于stack exchange,提问作者rediet yosef
相关产品推荐
相关产品推荐

