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
相关产品推荐
相关产品推荐

