Django如何找到反向FK的总和和反向FK的反向FK

时间:2021-01-08 18:44:29

标签: python django django-models

由于非常棒的数据库设计,我偶然发现了一个问题。我正在计算反向 FK 匹配和 ITS 反向 FK 匹配的数量(遵循此 SO 问题中的方法:Django QuerySet ordering by number of reverse ForeignKey matches)。我试着做:

assert 6 == Model.objects.annotate(counting=Count(f"blah1") + Count(f"blah1__blah2")).get(id=1).counting

但是我得到 6 == 7 因为在我的查询中总是给我一个额外的 1。这是为什么?

编辑:模型:

class Model(models.Model):
    ...

class Blah1(models.Model):
    parent = models.ForeignKey(Model, on_delete=models.CASCADE)

class Blah2(models.Model):
    parent = models.ForeignKey(Blah1, on_delete=models.CASCADE)

1 个答案:

答案 0 :(得分:1)

Count('blah1') 将计算与 Count('blah1__blah2') 相同数量的项目,因为您进行了 JOIN。事实上,查询看起来像:

SELECT model.*, COUNT(blah1.id) + COUNT(blah2.id) AS counting
FROM model
LEFT OUTER JOIN blah1.parent = model.id
LEFT OUTER JOIN blah2.parent = blah1.id

COUNT关心这些值,或者重复的值,它只会不计算 NULL,其余的,COUNT(blah1.id)COUNT(blah2.id) 可能几乎相同。

因此您应该计算 blah1唯一值:

from django.db.models import Count

Model.objects.annotate(
    counting=Count('blah1', distinct=True) +
             Count('blah1__blah2')
).get(id=1).counting

因此,这里我们将只计算不同的 blah1 对象。

相关问题