You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用单条Django查询统计各航班的已完成检查清单数量

问题描述

给定以下Django模型:

class Flight:
    # 模型其他字段省略,仅展示关联关系
    pass

class Checklist:
    flight = ForeignKey(Flight, on_delete=models.CASCADE)

class Item:
    checklist = ForeignKey(Checklist, on_delete=models.CASCADE)
    completed = BooleanField()

需求是统计每个Flight对应的已完成Checklist数量,判断Checklist完成的规则为:该Checklist下的所有Item的completed字段均为True。

已知针对Checklist可通过以下代码标注是否完成:

Checklist.objects.annotate(
    is_complete=~Exists(Item.objects.filter(
        completed=False, 
        checklist_id=OuterRef('pk'),
    ))
)

现需针对Flight实现类似逻辑,理想情况下使用单条查询,大致结构如下:

Flight.objects.annotate(
    completed_checklists=Count(
        Checklist.objects.annotate(<is complete annotation here>).filter(is_complete=True)
    )
)

解决方案

提供两种单查询实现方式,核心逻辑均为判断Checklist是否不存在未完成的Item:

方法一:利用FilteredRelation过滤后计数

from django.db.models import Exists, OuterRef, Count, FilteredRelation

Flight.objects.annotate(
    # 给关联的Checklist集合添加已完成的过滤关系
    completed_checklists_rel=FilteredRelation(
        'checklist_set',
        condition=~Exists(
            Item.objects.filter(
                checklist_id=OuterRef('checklist_set__pk'),
                completed=False
            )
        )
    )
).annotate(
    # 对过滤后的已完成Checklist进行计数
    completed_checklists=Count('completed_checklists_rel')
)

方法二:在Count中嵌套子查询

from django.db.models import Exists, OuterRef, Count, Subquery

Flight.objects.annotate(
    completed_checklists=Count(
        Subquery(
            Checklist.objects.filter(
                flight=OuterRef('pk'),
                # 直接判断当前Checklist无未完成Item
                ~Exists(Item.objects.filter(
                    checklist_id=OuterRef('pk'),
                    completed=False
                ))
            ).values('pk')
        )
    )
)

逻辑说明

  • 两种方案都通过~Exists(...)判断Checklist是否不存在completed=False的Item,以此标记该Checklist为已完成。
  • 方法一先通过FilteredRelation筛选出每个Flight下的已完成Checklist集合,再对该集合计数;方法二则直接通过子查询获取符合条件的Checklist主键,再统计数量。
  • 两种方式都能生成单条SQL查询,避免多次数据库交互,性能更优。

内容的提问来源于stack exchange,提问作者user15656060

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 09:15:41