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

如何用Django ORM按另一属性唯一值分组获取模型属性列表?

Django ORM按属性分组获取另一属性值列表

问题描述

现有如下Django模型:

class Result(models.Model):
    color = models.CharField()
    score = models.IntegerField()

数据库中有四条数据:

results = [
    Result(color="blue", score=5), 
    Result(color="blue", score=3), 
    Result(color="red", score=10), 
    Result(color="red", score=8),
]

希望通过Django ORM获取按color唯一值分组后的score列表,期望结果格式如下:

[
    {"color": "blue", "scores": [5, 3]}, 
    {"color": "red", "scores": [10, 8]},
]

已知可以通过以下代码按color分组计算平均分:

results.values("color").annotate(avg_score=Avg("score"))

想确认是否能通过Django的聚合/注解功能直接获取分组后的原始score列表。

解决方案

方法一:PostgreSQL专属方案(一步实现)

如果你的项目使用PostgreSQL数据库,可直接使用Django提供的ArrayAgg聚合函数完成需求:

from django.contrib.postgres.aggregates import ArrayAgg

# 按color分组,聚合score为列表
grouped_result = Result.objects.values("color").annotate(scores=ArrayAgg("score")).order_by("color")

执行后得到的QuerySet结构完全符合预期:

<QuerySet [{'color': 'blue', 'scores': [5, 3]}, {'color': 'red', 'scores': [10, 8]}]>

方法二:通用兼容方案(支持所有数据库)

若使用MySQL、SQLite等其他数据库,或需要跨数据库兼容,可以先查询全量数据,再用Python手动分组:

from itertools import groupby
from operator import attrgetter

# 先按color排序,保证groupby能正确分组
sorted_results = Result.objects.order_by("color")
grouped_data = []

# 遍历分组,整理成目标格式
for color, group in groupby(sorted_results, key=attrgetter("color")):
    grouped_data.append({
        "color": color,
        "scores": [item.score for item in group]
    })

最终grouped_data即为所需结果。

补充说明

  • ArrayAgg是PostgreSQL独有的聚合函数,依赖PostgreSQL数组类型,其他数据库无法使用。
  • 使用values()+annotate()时,values()指定的字段会作为分组键,聚合函数会针对每个分组计算结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:30:58