让我们首先解决总体问题:
django 中如何使用使用 OuterRef 的子查询注释查询集并计算子查询返回的对象数量(对于原始查询中的每个对象)
伪代码:
Model.objects.annotate(count=Count(Subquery(Model2.objects.filter(rel_id=OuterRef("id")).values_list("some_field").distinct())))
我有几个型号:
class Model1(models.Model):
model2 = models.ForeignKey(Model2, related_name="one_model2")
model2_m2m = models.ManyToMany(Model2, related_name="many_model2")
new_field = models.BooleanField()
class Model2(models.Model):
model3 = models.ForeignKey(Model3)
class Model3(models.Model):
...
我需要进行一个查询,检查每个 Model1 对象是否对于每个 Model2 相关对象(通过 model2 或 model2_m2m)其相关 model3 唯一计数大于 1。如果是,请将 new_field 设置为 True。
例如 model1 与 model2.model3 = 1 和 model2_m2m = [model2.model3 = 1] 相关 这会导致 new_field = False 但 model1 与 model2.model3 = 1 和 model2_m2m = [model2.model3 = 2] 相关 结果是真的
那么我的方法是什么?
我从 Model2 创建了 suquery:
sub_model2 = Model2.objects.filter(one_model2=OuterRef("id") | many_model2=OuterRef("id"))
然后用各种方式来注释Model1:
Model1.objects.annotate(my_annotation=Subquery(sub_model2.values_list("model3", flat=True).distinct().aggregate(<here is counting>)
导致错误This should be put in subquery(?不是吗?)[此查询集包含对外部查询的引用,只能在子查询中使用]
当尝试这样算时:
Model1.objects.annotate(my_annotation=Count(Subquery(sub_model2.values_list("model3", flat=True).distinct())
sub_model2 只要返回 1 个结果就可以。对于 2,它有一个问题,子查询返回超过 1 行(这不是我的 Count 的目的吗?)
还有其他一些具有相同的结果。
注意,在子查询上使用注释将导致始终返回 1,因为每个 model2 都与 model3 相关(大部分)。它永远不会概括它!
不,这个 Django 1.11 Annotating a Subquery Aggregate 是简单示例/解决方案的方法
您可以像这样计算子查询内的计数:
Model.objects.annotate(count=Subquery(Model2.objects.filter(rel_id=OuterRef("id")).annotate(count=Count("some_field", distinct=True)).values_list("count")[:1]))