Django多外键模型关联删除异常:如何保留关联日志模型?
嗨,我来帮你拆解这个问题,一步步搞清楚原因和解决办法~
问题分析与解决
为什么删除TestModel时会提示删除关联的TestModelLog?
核心原因是Django外键的on_delete参数默认值是CASCADE,哪怕你已经设置了null=True和blank=True,只要没显式指定其他on_delete行为,Django就会默认采用级联删除——也就是删除主表对象时,自动删除所有关联的子表对象。
另外我注意到你模型里的小笔误:TestModelLog的外键字段写的是TestModel_2,但你的主模型是TestModel,这应该是手滑写错了,得先修正这个,不然代码运行会报错哦。
如何实现删除TestModel后保留TestModelLog并置空外键?
要达到你想要的效果,只需要给外键字段显式指定on_delete=models.SET_NULL,这样当关联的TestModel对象被删除时,TestModelLog对应的外键字段会被设置为None,而不是删除整个TestModelLog实例。
修改后的模型代码:
from django.db import models from django.utils.six import python_2_unicode_compatible @python_2_unicode_compatible class TestModel(models.Model): description = models.CharField(max_length=34) def __str__(self): return "TestModel %s" % self.description @python_2_unicode_compatible class TestModelLog(models.Model): description = models.CharField(max_length=34) # 修正TestModel_2为TestModel,并添加on_delete=models.SET_NULL foreignkey = models.ForeignKey(TestModel, related_name='test_foreignkey_1', null=True, blank=True, on_delete=models.SET_NULL) foreignkey_2 = models.ForeignKey(TestModel, related_name='test_foreignkey_2', null=True, blank=True, on_delete=models.SET_NULL) def __str__(self): return "TestModelLog %s" % self.description
验证效果:
修改模型后记得执行迁移命令:
python manage.py makemigrations python manage.py migrate
之后再删除testmodel_a,你就可以通过以下代码验证效果:
# 先确保testmodel_b存在 testmodel_b = TestModel.objects.get(description='B_test') # 查询关联的TestModelLog result = TestModelLog.objects.get(foreignkey_2=testmodel_b) print(result.foreignkey) # 输出: None print(result.description) # 输出: Log
这样就实现了你想要的:删除关联的TestModel实例后,TestModelLog仍然保留,对应的外键字段被置为None。
内容的提问来源于stack exchange,提问作者David Foie Gras
相关产品推荐
相关产品推荐

