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

Django 1.11.3:调用实例方法抛异常时实例被删除是否为预期行为?

这绝对不是Django 1.11.3的预期行为

首先可以明确:Django不会因为你调用模型实例的未知方法(或者触发任何普通异常)就自动删除对应的数据库对象。这种情况几乎肯定是你的项目中存在自定义逻辑导致的,以下是一些常见排查方向:


1. 检查自定义异常处理逻辑

有没有在项目中设置全局异常捕获?比如:

  • 自定义的中间件,在捕获到AttributeError(调用未知方法会触发这个异常)时执行了对象删除操作;
  • 配置了LOGGING或者自定义异常处理器,在记录异常的同时删除了当前实例;
  • 视图/函数中的try-except块,在捕获异常后不小心调用了response_data.delete()。

2. 排查模型的自定义__getattr__方法

如果你给SomeModel重写了__getattr__方法,当调用不存在的属性/方法时会触发这个方法。如果该方法里有错误的逻辑,比如:

def __getattr__(self, name):
    # 错误示例:不小心删除了对象
    self.delete()
    raise AttributeError(f"'SomeModel' object has no attribute '{name}'")

就会导致调用未知方法时对象被删除。

3. 确认事务回滚的可能性

虽然Django默认是自动提交事务,但如果你的add_api_response方法是在一个手动开启的事务中,后续代码抛出异常会导致事务回滚,看起来像是对象被删除,但实际上是事务从未提交到数据库。你可以在创建对象后立刻查询数据库,确认对象是否真的被保存:

response_data = SomeModel.add_api_response(key=some_key, response=some_response)
# 创建后立刻查询
print(SomeModel.objects.filter(id=response_data.id).exists())  # 应该返回True
try:
    response_data.get()  # 触发异常
except AttributeError:
    print(SomeModel.objects.filter(id=response_data.id).exists())  # 再检查一次

如果第二次返回False,那大概率是事务回滚导致的;如果还是True,说明对象没被删除,只是你后续的查询逻辑有问题。

4. 检查Django信号接收器

有没有注册post_save、pre_delete或者异常相关的信号?比如某些信号接收器在特定条件下执行了删除操作,刚好和你触发的异常关联上了。


总结

这种行为完全不符合Django的默认设计,建议从上述几个方向逐步排查,找到项目中导致对象被删除的自定义逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:50:32