如何在多对多关系中分组查询模块及其关联组信息
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
相关产品推荐
相关产品推荐

