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

如何用子查询为Django QuerySet注释关联ModelB的UID列表?

问题分析与解决方案

错误原因

你用Subquery时直接返回了多行field_1__uid结果,但Django的Subquery作为annotate的字段值时,要求子查询每行只能输出单个值,不能返回多行结果,所以触发more than one row returned by a subquery used as an expression错误。

正确实现方式

根据你的需求(获取符合user__id__in=user_ids条件的所有ModelA关联的ModelB的UID列表),分两种场景给出实现:

场景1:每个ModelA实例返回自身关联的ModelB的UID列表(仅筛选符合用户ID条件的ModelA)

如果只需要查询type="year"且用户在指定列表中的ModelA,并给每个实例添加自身关联的ModelB的UID列表:

from django.db.models import ArrayAgg

user_ids = [1, 2, 3]
result = ModelA.objects.filter(
    type="year",
    user__id__in=user_ids
).annotate(
    model_b_uids_list=ArrayAgg("field_1__uid", distinct=True)
)
  • ArrayAgg会将当前ModelA关联的所有ModelB的UID聚合为一个数组;
  • distinct=True避免重复的UID(如果同一个ModelB被关联多次)。

场景2:所有ModelA实例(仅筛选type="year")都返回符合用户ID条件的全局ModelB的UID列表

如果要给所有type="year"的ModelA实例,都添加所有符合user__id__in=user_ids的ModelA关联的ModelB的UID集合:

from django.db.models import ArrayAgg, Subquery

user_ids = [1, 2, 3]
# 先通过子查询聚合符合条件的所有UID
agg_subquery = ModelA.objects.filter(user__id__in=user_ids).annotate(
    all_uids=ArrayAgg("field_1__uid", distinct=True)
).values("all_uids")[:1]  # 限制返回单行

result = ModelA.objects.filter(type="year").annotate(
    model_b_uids_list=Subquery(agg_subquery)
)
  • 子查询里用ArrayAgg将所有符合条件的UID聚合为一个数组,再通过[:1]确保返回单行;
  • 外层Subquery就能正常将这个数组作为注释字段的值。

关于你尝试的ArrayAgg无效的可能原因

大概率是没有正确结合查询条件或聚合逻辑:

  • 没有指定distinct=True导致重复值干扰;
  • 子查询没有限制返回单行,依然返回多行结果;
  • 没有正确关联外层查询或筛选条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:08:18