You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework创建实例时从request取数据报无email属性如何解决

问题根因与修复方案

你遇到的报错及其他潜在问题可按以下步骤修复:

1. 修复视图类嵌套错误

你的EmailForVerificationView存在重复嵌套定义的笔误,直接删掉多余的内层类定义即可。

2. 修复实例创建逻辑错误

objects.create() 执行后会自动写入数据库,返回创建好的模型实例,不需要链式调用.save(),否则save()返回的None会导致后续取值失败。如果你实际运行中出现'Request' object has no attribute 'email',请检查你是否手误把request.data['email']写成了request.email。

3. 修复模型字段取值逻辑

Django模型实例直接通过属性访问取字段值,不要用.get()方法。

4. 修复验证码生成类型不匹配问题

你当前的验证码生成函数返回整数,存到CharField字段会丢失前导零,另外原逻辑中random.randint(0,10)会生成10这个两位数,会导致验证码长度超过6位,需要调整取值范围。

5. 补充校验视图的异常捕获

避免邮箱不存在时直接抛出500错误,同时校验失败返回404不符合语义,建议改成400状态码。


修正后的 views.py

from django.shortcuts import get_object_or_404

class Verify_code(APIView):
    def post(self, request):
        data = request.data
        code = data.get('code')
        email = data.get('email')
        # 捕获邮箱不存在的情况,避免服务端报错
        email_for_verification = get_object_or_404(models.Email_for_Verification, email=email)
        if code == email_for_verification.code:
            return Response({"valid" : "Valid code", "email": email}, status=status.HTTP_200_OK)
        else :
            return Response({"invalid" : "Invalid code", "email": email}, status=status.HTTP_400_BAD_REQUEST)
        

class EmailForVerificationView(CreateAPIView):
    queryset = models.Email_for_Verification.objects.all()
    serializer_class = EmailForVerificationSerializer
    def create(self, request):
        # 去掉多余的save()调用,create方法本身就会完成数据持久化
        created = models.Email_for_Verification.objects.create(email=request.data['email'])
        # 直接用属性访问取模型字段值
        email = created.email
        code = created.code
        send_mail(
            'Here is the code of verification',
            code,
            'dummy@mail.com',
            [email],
            fail_silently=True,
        )
        return Response({"code" : code, "email": email}, status=status.HTTP_200_OK)

修正后的 models.py

import random
def generate_activation_code():
    # 直接返回字符串,避免前导零丢失,同时取值范围调整为0-9保证单个字符长度为1
    return ''.join([str(random.randint(0,9)) for _ in range(6)])

class Email_for_Verification(models.Model):
    email = models.EmailField(
        max_length=100, verbose_name='email', unique=True)
    code = models.CharField(max_length=6, default=generate_activation_code)

优化建议

  • 建议给邮箱验证记录加过期时间字段,避免验证码长期有效产生安全风险
  • 发送邮件的逻辑建议改成异步执行,避免接口响应过慢
  • 校验成功后建议删除对应验证记录,避免被重复使用

内容的提问来源于stack exchange,提问作者Zero0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 18:39:03