【问题标题】:django many_to_many field deletiondjango many_to_many 字段删除
【发布时间】:2018-10-18 09:03:42
【问题描述】:

我有两个 django 模型,我想使用多对多关系连接它们。请看下面的例子:

class A(models.Model):
    name = models.CharField(max_length=1000, unique=True)

class B(models.Model):
    name = models.CharField(max_length=1000, unique=True)
    aa = models.ManyToManyField(A, related_name='bs', blank=True, null=True)

我想弄清楚如果我删除 A 或 B 的记录会发生什么?我想要发生的是 M2M 中的关系被删除,但另一个对象保持不变。假设A中的一行被删除,那么B中的相关行应该保留,只有通过m2m关系的连接应该被删除。我在 Django 文档中找不到它。

【问题讨论】:

    标签: django django-models many-to-many django-orm


    【解决方案1】:

    是的,在documentation中有说明。

    以下是相关部分:

    如果我们删除出版物,其文章将无法访问它:

    p1.delete()
    Publication.objects.all() <QuerySet [<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>]>
    a1 = Article.objects.get(pk=1)
    a1.publications.all()
    <QuerySet []>

    如果我们删除一篇文章,其出版物将无法访问它:

    a2.delete()
    Article.objects.all()
    <QuerySet [<Article: Django lets you build Web apps easily>]>
    p2.article_set.all()
    <QuerySet []>

    在您的情况下,Django 将为模型 AB 以及一个中间表创建表,这不会反映在模型中。当您删除类 A 的对象实例(一条记录)时,将删除表 A 中的关联行,以及中间表中的所有关联行. B 表不会受到影响。

    【讨论】:

    • 但是如果 B 实例与许多 A 实例相关,那么我们删除其中一个 A 实例,与 B 相关的左侧实例会发生什么情况,我们可以随时访问它们吗?
    • @SidouMahmoud 由于 A 和 B 通过多对多 (m:n) 关系连接,因此从表 A 中删除一条记录不会影响其他记录的关系。答案是肯定的,如果你有与B1相关的A1、A2和A3,你删除A1,A2和B1以及A3和B1之间的关系保持不变。
    【解决方案2】:

    通过建立 m2m 关系,您基本上是在创建另一个表,其中包含模型 A 的外键和模型 B 的外键(Django 为您完成)。

    默认情况下,on_delete 设置为 models.CASCADE,这意味着如果您删除任何这些模型中的一行,该关系也将被删除。 (您可以通过删除管理页面中的一行来确认它,您会看到一条消息,其中列出了它们也将被删除的所有关系)

    您可以自己制作一个表来管理这些事情,并将该表连接到具有through= 的模型。这是以您真正想要的方式管理 m2m 关系的好方法。

    文档:Many-to-many relationships

    【讨论】:

    • 很好的答案,但我有一点要说。你确定ManyToManyFieldon_delete 参数吗?
    • 或者我误解了什么。你的意思是连接 A 和 B 的中间表默认会级联吗?
    • @cezar 不在 manytomany 字段中。在 django 为您制作的表中,对于涉及多线程的每个模型和这些字段(它们是外键字段),将有 2 个字段一个,on_delete 设置为models.CASCADE,您可以通过自己制作模型来更改它并将其与through 连接,而不是让 django 为您使用默认设置。
    • 谢谢!是的,根据我的第二条评论,我意识到你试图解释什么。现在完全清楚了。
    猜你喜欢
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 2021-11-19
    • 2016-03-22
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多