当前位置: 首页 > 知识库问答 >
问题:

反向外键上的Django级联删除

班承恩
2023-03-14

Django演示了如何设置或覆盖在文档中使用外键的级联删除。

model = models.ForeignKey(MyModel, null = True, on_delete = models.SET_NULL)

但是如果我们想让这种效果反过来呢?如果我们希望fk模型的删除导致该模型的删除,该怎么办?

谢谢

共有2个答案

甄伟兆
2023-03-14

我不认为你看到的特性是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]
空鸿云
2023-03-14

有一个非常微妙的实现点,我认为我应该补充到这个讨论中。

假设我们有两个模型,其中一个通过外键引用另一个,如中所示:

class A(models.Model):
    x = models.IntegerField()

class B(models.Model):
    a = models.ForeignKey(A, null=True, blank=True)

现在,如果我们删除A的条目,级联行为将导致B中的引用也被删除。

到目前为止,一切都好。现在我们要扭转这种行为。正如人们提到的,显而易见的html" target="_blank">方法是使用删除过程中发出的信号,所以我们去:

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,它将尝试删除已删除的项!

诀窍是,您需要EXCEPTION HANDLING来正确实现反向级联:

def delete_reverse(sender, **kwargs):
    try:
        if kwargs['instance'].a:
            kwargs['instance'].a.delete()
    except:
        pass

这段代码将以任何方式工作。我希望它能帮助一些人。

 类似资料:
  • 问题内容: 我有两个像这样的表: 因此,逻辑很简单,用户删除了类别x下​​的所有书籍,从猫中删除了x之后,我尝试了上述方法,但不起作用,在我清理了表格书籍后,表格类别仍被填充,这是怎么回事? 问题答案: 具有级联删除功能的外键意味着,如果删除父表中的记录,则子表中的相应记录将被自动删除。这称为级联删除。 您说的是相反的意思,这不是当您从子表中删除时会将记录从父表中删除。 ON DELETE CAS

  • 问题内容: 我有一个场地,这个场地上发生了很多事件。我的模型如下所示: 我想显示在某个场所发生的所有事件。我怎样才能做到这一点?我当前的视图如下所示: 问题答案: 您可以使用另一种方式。 请注意,是经理的对象,像,这样你就可以打电话,,和类似它来得到一个查询集。 请参阅Django文档

  • 问题内容: 我有一个场地,这个场地上发生了很多事件。我的模型如下所示: 我想显示在某个场所发生的所有事件。我怎样才能做到这一点?我当前的视图如下所示: 问题答案: 你可以使用另一种方式。 请注意,是经理的对象,像,这样你就可以打电话和类似它来得到一个查询集。

  • 问题内容: 我想使用外键来保持完整性并避免使用孤立键(我已经使用过innoDB)。 如何创建在CASCADE上删除的SQL语句? 如果我删除一个类别,那么如何确保它不会删除也与其他类别相关的产品。 数据透视表“ categories_products”在其他两个表之间创建多对多关系。 问题答案: 如果您的级联删除某个产品是因为该产品属于被杀类别的成员,那么它会删除该产品,那么您的外键设置不正确。给

  • 在数据库中,将有一个列,并对的列具有外键约束。 对于在删除时级联的外键约束,可能执行的一些操作包括、和。这给出了以下方案组合。 a:在JPA中对父级进行级联删除调用,在删除父行时删除数据库中的子级。 b:在JPA中级联删除,在父删除时将子表中的外键列设置为null。在这种情况下,@joincolumn中的和中的可能需要为true/false。 C:在JPA中进行级联删除,在数据库中对外键删除不做任

  • 问题内容: 我有以下示例: 我想在级联排如果双方并从各自的表被删除。 删除两个外键后,如何在表C中级联自身? 如果仅删除一个FK,则受影响的行应在引用该外键的列中更改为空值。 问题答案: 我建议使用两个外键约束和一个触发器来处理其余的 表格: 扳机: SQL提琴。 确保连接表具有替代PK列。无论如何都不能是PK,因为那将不允许两者都为NULL。而是添加一个约束,该约束允许使用NULL值。 触发器针