CASCADE 究竟如何与 Django 中的多对多字段一起工作

Posted

技术标签:

【中文标题】CASCADE 究竟如何与 Django 中的多对多字段一起工作【英文标题】:How exactly does CASCADE work with ManyToMany Fields in Django 【发布时间】:2020-08-09 07:19:41 【问题描述】:

我想知道 CASCADE 究竟是如何与 Django 中的多对多字段一起工作的。

一个简短的例子:

class Project(Model):
    name = TextField(null=False)

class Job(Model):
    projects = ManyToManyField(Project, on_delete=CASCADE, null=False)
    name = TextField(null=False)

如您所见,我在这里有一个 ManyToManyField。所以基本上一个项目可以有多个工作,一个工作可以属于多个不同的项目。我想要的是只有当它所属的所有项目都被删除时才会自动删除作业。 CASCADE 在这种情况下会这样工作吗?

【问题讨论】:

它删除所有与级联表链接的链行。 当项目本身被删除时,它会删除相关的行(所有作业),在你的情况下它完全没用,看看信号,或者模型管理器方法.clear() 并手动实现逻辑你想要 【参考方案1】:

CASCADE 不能那样工作。在您的情况下,使用 CASCADE,有两个项目 A 和 B,一个作业 J_DAILY 链接到这两个项目,如果您删除项目 A,那么 J_DAILY 也将被删除。

如果您希望您的工作“坚持到最后一个项目”。您应该将您的 on_delete 更改为 DO_NOTHING 并添加检查删除项目。

@receiver(pre_delete, sender=Project)
def delete_related_jobs(sender, instance, **kwargs):
    for job in instance.job_set.all():
        # No remaining projects
        if not job.projects.exclude(id=instance.id).count():
               job.delete()

【讨论】:

以上是关于CASCADE 究竟如何与 Django 中的多对多字段一起工作的主要内容,如果未能解决你的问题,请参考以下文章

如何从django orm中的多对多关系表中提取数据

使 ModelForm 与 Django 中的中间模型的多对多关系工作的步骤是啥?

如何过滤和访问 Django QuerySet 中的多对多字段?

Django,在 self 类中的多对多关系中,我如何在 ORM 方面相互引用?

如何在引导选项卡块中按 django 模板中的多对多字段过滤对象

Django 管理中的多对多:选择无