由于非常棒的数据库设计,我偶然发现了一个问题。我正在计算反向 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)
答案 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
对象。