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

如何通过Django ORM从Employee查询集按Business分组生成列表字典

Django ORM按Business分组员工(单查询实现)

先明确你的模型结构(示例):

from django.db import models

class Business(models.Model):
    name = models.CharField(max_length=100)
    # 其他业务字段

class Employee(models.Model):
    name = models.CharField(max_length=100)
    business = models.ForeignKey(Business, on_delete=models.CASCADE, related_name='employees')
    # 其他员工字段

方案1:PostgreSQL环境下用聚合函数直接分组(推荐)

如果你的项目用PostgreSQL,可以利用Django提供的ArrayAgg或JSONBAgg聚合函数,直接在数据库层面完成分组,返回企业-员工列表的结构,全程单查询:

聚合员工字段(如姓名)

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

# 查询每个企业及其对应的员工姓名列表
business_employee_map = Business.objects.annotate(
    employee_names=ArrayAgg(F('employees__name'))  # 可替换为你需要的员工字段
).values('name', 'employee_names')

# 转成目标字典
result = {item['name']: item['employee_names'] for item in business_employee_map}

聚合完整员工对象

如果需要完整的员工对象数据,用JSONBAgg将员工字段序列化为JSON数组:

from django.contrib.postgres.aggregates import JSONBAgg
from django.db.models.functions import JSONObject

business_employee_map = Business.objects.annotate(
    employees_list=JSONBAgg(
        JSONObject(
            id=F('employees__id'),
            name=F('employees__name'),
            # 按需添加其他员工字段
        )
    )
).values('name', 'employees_list')

result = {item['name']: item['employees_list'] for item in business_employee_map}

方案2:从Employee查询集出发分组

如果你只能从Employee查询集入手(比如已经有employees = Employee.objects.select_related('business').all()),可以通过values+聚合函数实现分组:

from django.db.models import ArrayAgg

# 按企业分组,聚合员工姓名
employee_groups = Employee.objects.values(
    'business__name'  # 按企业名称分组,也可用business__id保证唯一性
).annotate(
    employee_names=ArrayAgg('name')
).order_by('business__name')

result = {item['business__name']: item['employee_names'] for item in employee_groups}

方案3:适配MySQL等其他数据库

如果用MySQL,没有原生的ArrayAgg,可以自定义GROUP_CONCAT函数实现字符串聚合,之后再拆分:

from django.db.models import Func, F

class GroupConcat(Func):
    function = 'GROUP_CONCAT'
    template = "%(function)s(%(expressions)s SEPARATOR ', ')"

employee_groups = Employee.objects.values(
    'business__name'
).annotate(
    employee_names=GroupConcat(F('name'))
).order_by('business__name')

# 拆分字符串为列表
result = {item['business__name']: item['employee_names'].split(', ') for item in employee_groups}

以上所有方案均为单数据库查询,无需循环遍历每个Employee对象处理分组逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:40:23