django 使用基于查询的聚合值注释模型

Eri*_*ric 5 django django-models django-queryset django-aggregation django-annotate

假设我有以下模型结构:

Parent():

Child():
parent = ForeignKey(Parent)

GrandChild():
child = ForeignKey(Child)
state = BooleanField()
num = FloatField()
Run Code Online (Sandbox Code Playgroud)

我正在尝试从 ParentViewSet恢复以下内容:

  1. 孩子的数量。
  2. 'state' 为 True 时的 'num' 字段的总和。

我可以执行以下操作:

queryset = Parent.objects\
    .annotate(child_count=Count('child'))\
    .annotate(sum_total=Sum('child__grandchild__num'))
Run Code Online (Sandbox Code Playgroud)

这给了我 (1) 但不是 (2) 它给了我所有孙子的总和。如何在确保所有Parent对象仍在 QuerySet 中的同时适当地过滤孙子?

Pat*_*ick 5

您使用的是哪个版本的 django?如果版本受支持,您也可以使用子查询。

from django.db.models import OuterRef, Subquery

Parent.objects
.annotate(child_count=Count('child'))
.annotate(
    grandchild_count_for_state_true=Subquery(
        GrandChild.objects.filter(
            state=True,
            child=OuterRef('pk')
        ).values('parent')
        .annotate(cnt=Sum('child__grandchild__num'))
        .values('cnt'),
        num=models.IntegerField()
    )
)
Run Code Online (Sandbox Code Playgroud)

您可以通过聚合查询对此进行优化。


Arp*_*nki 1

尝试在注释之前使用过滤器

queryset = Parent.objects.filter(child__grandchild__state='True')\
    .annotate(child_count=Count('child'))\
    .annotate(sum_total=Sum('child__grandchild__num'))
Run Code Online (Sandbox Code Playgroud)