【问题标题】:Django - Many To Many after filtering one end of the relationship, counting backwards always produces the value 1Django - 多对多过滤关系的一端后,向后计数总是产生值1
【发布时间】:2017-02-19 11:04:18
【问题描述】:

我有两个处于多对多关系的模型,我希望出现以下效果:

  • 考虑模型 AB 彼此之间存在多对多关系。
  • AB 的相关名称是 bsBA 的相关名称是 as
  • 每当我创建一个AB 时,它总是会立即连接到另一个或多个,因此最初AB 的所有实例都至少有一个相关对象。李>
  • 如果我想删除一个A(我们称它为a0),我希望它删除所有Bs,在A被删除后,没有相关的A,所以基本上我想删除所有在其相关集as 中只有a0B(也可以预期相反的示例)。

我试图实现这一点的方式是,当我想删除 A (例如 a0)时,我会说:

a0.bs.annotate(Count('bs')).filter(bs__count=1).delete()

但是这会无条件地删除a0.bs中所有相关的B实例,当我去shell测试它时,我会得到这个结果:

>>> a0.bs.annotate(Count('bs')).values_list('bs__count',flat=True)
<QuerySet [1, 1, 1, 1]>
>>> B.objects.filter(as=a0).annotate(Count('bs')).values_list('bs__count',flat=True)
<QuerySet [1, 1, 1, 1]>

但如果我对同一个数据库实例执行此操作,我也会得到这个:

>>> B.objects.annotate(Count('bs')).filter(as=a0).values_list('bs__count',flat=True)
<QuerySet [1, 4, 6, 6]>

因此,这 4 个 B 实例中有 3 个不能满足 count == 1,但如果我在注释之前过滤我想要查看的特定 B 实例,它们都满足,这似乎比使用的最后一个命令(具有准确结果的命令)效率更高。

谁能告诉我关于这种效果的任何见解?

【问题讨论】:

  • 这不是数学题,要使用 A、B、a0 和 b0,请使用正确的变量名

标签: django database filter count many-to-many


【解决方案1】:

你不能假设任何没有任何相关 A 记录的 B 记录也应该被删除吗?反之亦然。

A.objects.filter(pk=1).delete()
B.objects.filter(as=None).delete()

【讨论】:

    猜你喜欢
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 2012-05-16
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2021-03-19
    相关资源
    最近更新 更多