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

Django异常块内执行Model.objects.create数据未入库问题

问题现象

开发Django应用时出现异常场景:在抛出异常前、或except异常捕获块内执行Model.objects.create(**obj)时,代码运行无报错,但数据库中查询不到对应创建的对象,执行Model.objects.all()也无法返回该记录。

单步测试代码:

Model.objects.create(**obj)

完整业务代码如下:

def has_permission(self, request, view):
        try:
            serializer = VerifyOTPRequestSerializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            otp = request.data.pop("otp")
            flow = request.data.pop("flow")
            primary_phone = request.data.get("contact_detail", {}).get(
                "primary_phone", ""
            )            
            if OTPFailedAttempts.objects.filter(phone=primary_phone).count() > 0:
                raise Exception("otpAttemptError")
            
            return helpers.OTPHelper.verify_otp(primary_phone, otp, flow)
        except Exception as permission_error:
            
            OTPFailedAttempts.objects.create(**{"phone": primary_phone, 'email': email})

            return False

补充数据库配置:

ATOMIC_REQUESTS = True

核心疑问:该问题是Django本身限制了异常场景附近的模型对象创建操作,还是代码写法存在错误?

问题成因

该问题和Django的事务机制、代码逻辑缺陷都有关系,不是Django刻意限制异常场景的写入操作:

  • 配置ATOMIC_REQUESTS = True后,Django会将每个请求的整个视图处理流程(包括DRF的认证、权限、限流校验逻辑)包裹在一个全局数据库事务中,只有请求链路全程无未捕获异常、正常返回响应时才会提交全量事务;只要最终有异常抛出触发事务回滚,事务内的所有数据库写入操作都会被撤销。
  • 代码中except块执行完创建操作后直接return False,DRF框架收到has_permission返回的False结果后,会自动抛出PermissionDenied异常生成403响应,该异常会触发全局请求事务回滚,except块中写入的OTPFailedAttempts记录属于同一个事务,会被同步回滚,因此数据库中查询不到。
  • 代码存在隐藏逻辑bug:except块中使用的email变量、部分异常分支下的primary_phone变量没有提前赋值。如果触发异常的路径未走到变量赋值的代码行,create语句会直接抛出NameError,又被代码中全量捕获Exception的逻辑吞掉,既不会暴露报错,也不会完成实际写入。
修复方案
  • 异常场景下必须持久化的写入操作,单独开启独立事务执行,和全局请求事务做隔离,避免被外层回滚逻辑影响:
from django.db import transaction

# 替换except块中的原有创建逻辑
with transaction.atomic():
    # 提前校验所有传入字段已正确赋值
    OTPFailedAttempts.objects.create(phone=primary_phone, email=email)
  • 修复变量未定义问题:将primary_phone、email等字段的取值逻辑移到try块最前端,或在取值时增加默认值判断,确保所有进入except块的路径下,创建模型需要的字段都已完成赋值。
  • 不要裸抛、全量捕获Exception,针对性捕获业务类异常即可,避免吞掉序列化校验失败、变量未定义、数据库连接错误等非预期异常,干扰问题排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:30:43