Django REST Framework实现邮箱验证码校验遇QuerySet无code属性报错求助
实现思路评估
整体功能逻辑符合邮箱验证的常规实现方案,核心流程(生成验证码存库→发送至用户邮箱→用户回填校验)没有方向性问题,仅代码细节存在多处错误需要修正。
报错原因说明
你遇到的'QuerySet' object has no attribute 'code'属于Django ORM的常见误用:
objects.filter()返回的是符合条件的查询集(QuerySet),是多个模型实例的集合,不是单个实例,因此无法直接访问code属性。- 因为
email字段已经设置了unique=True约束,同一个邮箱只会存在一条记录,应该用objects.filter(email=email).first()获取单个实例,或者直接用objects.get(email=email)查询。
其他需要修正的问题
1. 验证码生成逻辑错误
你定义的generate_activation_code返回的是int类型,但模型中code字段为CharField,类型不匹配;另外random.randint(0,10)会生成0到10的整数,包含10这个两位数,最终生成的验证码长度会超出6位,建议修改为:
def generate_activation_code(): return ''.join([str(random.randint(0,9)) for _ in range(6)])
2. 视图逻辑缺陷
- 没有做邮箱存在性判断,如果请求的邮箱不在数据库中,直接取
code属性会抛出异常 - 验证码对比时,请求传入的
code是int类型,数据库存储的是字符串,直接对比会永远不相等 - 验证成功返回的状态码误用了
404 Not Found,验证成功应返回200,验证失败返回400 - 缺少验证码过期、校验后销毁的逻辑,存在安全风险,建议给模型增加过期时间字段,校验通过后删除对应记录避免重复使用
3. 修正后的视图代码参考
class Verify_code(APIView): def post(self, request): data = request.data req_code = str(data.get('code', '')) email = data.get('email', '') # 校验参数完整性 if not req_code or not email: return Response({"error": "邮箱和验证码不能为空"}, status=status.HTTP_400_BAD_REQUEST) # 查询对应验证记录 verify_record = models.Email_for_Verification.objects.filter(email=email).first() if not verify_record: return Response({"error": "该邮箱未申请验证码"}, status=status.HTTP_400_BAD_REQUEST) # 校验验证码 if req_code == verify_record.code: # 校验成功,删除记录避免重复使用 verify_record.delete() return Response({"valid": "Valid code", "email": email}, status=status.HTTP_200_OK) return Response({"error": "验证码错误"}, status=status.HTTP_400_BAD_REQUEST)
内容的提问来源于stack exchange,提问作者Zero0
相关产品推荐
相关产品推荐

