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

Django ORM如何对分组后的外键关联结果进行过滤查询

实现方案

你可以通过Subquery结合OuterRef的方式实现,最终直接拿到完整的Person类型QuerySet,代码如下:

from django.db.models import OuterRef, Subquery

# 子查询:获取每个Person对应的最新Result记录的主键
latest_result_subq = Result.objects.filter(
    person_id=OuterRef("pk")
).order_by("-time").values("pk")[:1]

# 外层查询:筛选符合条件的Person
person_qs = Person.objects.filter(
    result__pk=Subquery(latest_result_subq),
    result__outcome__in=[2, 3]
).distinct()

方案说明

  • OuterRef("pk")用于引用外层查询中Person表的主键,实现子查询与外层表的关联
  • 子查询按time字段倒序后取第一条,得到每个Person最新的Result记录主键
  • 外层查询直接对Person表做筛选,关联最新Result记录的同时过滤outcome值,最终返回的就是完整的Person QuerySet,保留所有字段
  • 末尾加distinct()是为了避免关联查询产生重复的Person记录

替代方案(基于注解+F表达式)

如果你更习惯用分组注解的方式,也可以用以下写法:

from django.db.models import Max, F

person_qs = Person.objects.annotate(
    latest_time=Max("result__time")
).filter(
    result__time=F("latest_time"),
    result__outcome__in=[2, 3]
).distinct()

注意事项

如果存在同一个Person同一时间有多条Result记录的情况,可以在子查询的排序规则中追加-id,确保每次只取唯一的最新记录:

latest_result_subq = Result.objects.filter(
    person_id=OuterRef("pk")
).order_by("-time", "-id").values("pk")[:1]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 19:45:08