【问题标题】:Django many to many relations on deleteDjango删除多对多关系
【发布时间】:2015-08-22 19:01:43
【问题描述】:

我有以下型号:

class Branch(models.Model):
    releases = models.ManyToManyField(Release)


class Release(models.Model):
    #fields

当你删除一个发布对象时,默认的 django 行为是什么(在我的例子中?)它会删除所有只与该发布相关的分支对象吗?我猜如果没有设置它 null=True 那么如果我尝试删除所有版本它将为我提供正确的 IntegrityError ,因为版本将为空。如果我将它设置为 null=True,那么我猜如果相关对象被删除,它只会将发布作为一个空列表。当一个版本被删除并且分支对象在版本中没有相关对象时,是否可以删除所有相关分支?

例如

r1 = Release()
r1.save()
r2 = Release()
r2.save()
b1 = Branch()
b1.save()
b1.releases.add(r1)
b2 = Branch()
b2.save()
b2.releases.add(r2)
r1.delete() #this should delete b1 because releases is empty

这种行为可能吗?

【问题讨论】:

    标签: python django m2m


    【解决方案1】:

    null 在ManyToMany 关系中无效。

    在 Django 中,M2M 关系是represented via an intermediary table,这是自动生成的。添加null=True/False 不会影响此中间表的构建方式,并且父对象始终可以没有相关的子对象。

    blank 是影响是否允许创建带有或不带有子对象的父对象的选项,但这不是数据库级别的限制,它只是代码级别的验证。

    实现您正在寻找的级联删除的方式是使用post_delete 信号。大致如下:

    from django.db.models.signals import post_delete
    from django.dispatch import receiver
    
    class Branch(models.Model):
        releases = models.ManyToManyField(Release)
    
    class Release(models.Model):
        #fields
    
    @receiver(post_delete, sender=Release)
    def cascade_delete_branch(sender, instance, **kwargs):
       # code to handle Branch removal
    

    【讨论】:

      猜你喜欢
      • 2011-09-14
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-28
      相关资源
      最近更新 更多