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

如何在多对多关系中分组查询模块及其关联组信息

Django多对多关系数据分组格式化问题

问题背景

模型定义如下:

class Module(BaseModel):
    name = models.TextField(unique=True, null=False)
    groups = models.ManyToManyField(ModuleGroup, db_table='module_group_members')

class ModuleGroup(BaseModel):
    name = models.TextField(unique=True, null=False)

期望获取的输出格式:

[
    {
        'name': 'name1',
        'groups': ['group1', 'group2']
    },
    {
        'name': 'name2',
        'groups': ['group6', 'group7']
    }
]

尝试以下代码后:

modules = Module.objects.filter(is_active=True)
print('values_list', list(modules.values('name', 'groups')))

得到的结果是重复的模块记录:

[
    {'name': 'name1', 'groups__name': 'group2'},
    {'name': 'name1', 'groups__name': 'group2'},
    {'name': 'name2', 'groups__name': 'group6'},
    {'name': 'name2', 'groups__name': 'group7'}
]

需要将相同模块的组名合并到一个列表中。


解决方案

方法一:数据库层面聚合(PostgreSQL专属)

利用Django的ArrayAgg聚合函数,直接在数据库端完成分组和组名聚合,效率更高:

from django.contrib.postgres.aggregates import ArrayAgg
from django.db.models import F

# 聚合关联的组名,去重后存入groups字段
modules = Module.objects.filter(is_active=True).annotate(
    groups=ArrayAgg(F('groups__name'), distinct=True)
).values('name', 'groups')

# 输出结果就是期望格式
print(list(modules))

方法二:Python层面处理(兼容所有数据库)

先通过prefetch_related批量预取关联数据,避免N+1查询,再遍历整理格式:

modules = Module.objects.filter(is_active=True).prefetch_related('groups')

result = []
for module in modules:
    result.append({
        'name': module.name,
        'groups': [group.name for group in module.groups.all()]
    })

print(result)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:02:09