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

Django中如何用字典在注解里转换ArrayAgg的城市ID为名称?

解决方案

方法一:Python层面映射(简单高效)

既然已经在Python内存中拥有cities字典,最直接的方式是先查询出包含city_ids的公司列表,再遍历每个公司完成ID到城市名的映射:

from django.db.models import Subquery, OuterRef, ArrayAgg
from django.contrib.postgres.fields import ArrayField

# 先查询所有公司及其对应的地址ID数组
companies = list(
    Company.objects.all()
    .annotate(
        city_ids=Subquery(
            ThroughCompanyAddress.objects.filter(company_id=OuterRef("id"))
            .order_by()  # 避免Postgres要求排序的报错
            .aggregate(arr=ArrayAgg("address_id"))["arr"],
            output_field=ArrayField(models.IntegerField())
        )
    )
)

# 遍历映射城市名称
for company in companies:
    # 处理city_ids为None的情况,避免报错
    company.cities = [cities.get(address_id, "") for address_id in (company.city_ids or [])]

这种方法无需依赖数据库特殊函数,逻辑直观,适合大多数跨库场景。

方法二:数据库层面注解(直接在查询中生成结果)

如果需要在数据库查询阶段直接得到城市名称数组,可以利用PostgreSQL的JSONB函数实现动态映射:

步骤1:导入必要模块

import json
from django.db.models import Func, Value, JSONField, Subquery, OuterRef, ArrayAgg
from django.contrib.postgres.fields import ArrayField

步骤2:执行查询并完成映射

# 将Python字典转为JSON字符串,传入数据库
cities_json = json.dumps(cities)

companies = (
    Company.objects.all()
    .annotate(
        city_ids=Subquery(
            ThroughCompanyAddress.objects.filter(company_id=OuterRef("id"))
            .order_by()
            .aggregate(arr=ArrayAgg("address_id"))["arr"],
            output_field=ArrayField(models.IntegerField())
        )
    )
    .annotate(
        cities=Func(
            # 传入JSON格式的城市映射表
            Value(cities_json, output_field=JSONField()),
            # 将city_ids数组拆分为单个元素并转为文本类型
            Func(Func(F('city_ids'), function='unnest'), function='text'),
            # 聚合回数组
            function='jsonb_extract_path_text',
            template='array_agg(%(function)s(%(expressions)s))',
            output_field=ArrayField(models.CharField())
        )
    )
)

该方法通过PostgreSQL的jsonb_extract_path_text和array_agg函数,在数据库内部完成ID到城市名的映射并聚合为数组,适合需要直接将结果用于后续数据库操作的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:17:39