Django 展示了如何在文档中使用外键设置或覆盖级联删除。
model = models.ForeignKey(MyModel, null = True, on_delete = models.SET_NULL)
但是,如果我们反过来想要这种效果呢?如果我们希望删除 fk 模型导致删除这个模型怎么办?
谢谢
有一个非常微妙的实现点,我想我应该添加到这个讨论中。
假设我们有两个模型,其中一个通过外键引用另一个模型,如下所示:
class A(models.Model):
x = models.IntegerField()
class B(models.Model):
a = models.ForeignKey(A, null=True, blank=True)
现在,如果我们删除 A 的条目,级联行为将导致 B 中的引用也被删除。
到目前为止,一切都很好。现在我们想扭转这种行为。人们提到的明显方法是使用删除期间发出的信号,所以我们去:
def delete_reverse(sender, **kwargs):
if kwargs['instance'].a:
kwargs['instance'].a.delete()
post_delete.connect(delete_reverse, sender=B)
这似乎是完美的。它甚至可以工作!如果我们删除一个 B 条目,相应的 A 也将被删除。
问题是这有一个循环行为导致异常:如果我们删除 A 的一项,由于默认的级联行为(我们想要保留),B 的相应项也将被删除,这将导致delete_reverse 被调用,它试图删除一个已经删除的项目!
诀窍是,您需要异常处理才能正确实现反向级联:
def delete_reverse(sender, **kwargs):
try:
if kwargs['instance'].a:
kwargs['instance'].a.delete()
except:
pass
这段代码无论哪种方式都可以工作。我希望它可以帮助一些人。
我不认为您正在查看的功能是 ORM 或数据库概念。您只想在删除某些内容时执行回调。
所以使用post_delete
信号并在那里添加你的回调处理程序
from django.db.models.signals import post_delete
from django.dispatch import receiver
from myapp.models import MyModel
@receiver(post_delete, sender=MyModel)
def my_post_delete_callback(sender, **kwargs):
#Sender is the model which when deleted should trigger this action
#Do stuff like delete other things you want to delete
#The object just deleted can be accessed as kwargs[instance]