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

如何在Django中关联不同模型的QuerySet生成含新增字段的新查询集

解决方案

方案1:Python内存合并(适合小数据量场景)

逻辑简单易维护,适合查询范围内数据量在万级以下的场景,自动兼容某日期仅存在单渠道销售数据的情况:

# 把两个查询集转为以销售日期为key的字典
a_map = {item["sales_date"]: item["store_sales"] for item in querysetA}
b_map = {item["sales_date"]: item["online_sales"] for item in querysetB}

# 取两个查询集的所有日期,去重后排序
all_sales_dates = sorted(set(a_map.keys()).union(b_map.keys()))

# 构造最终的合并结果
querysetC = []
for index, sales_date in enumerate(all_sales_dates, 1):
    store_sales = a_map.get(sales_date, 0.00)
    online_sales = b_map.get(sales_date, 0.00)
    querysetC.append({
        "id": index,
        "sales_date": sales_date,
        "store_sales": store_sales,
        "online_sales": online_sales,
        "combine_sales": store_sales + online_sales
    })

方案2:ORM数据库层查询(适合大数据量场景)

直接在数据库层面完成关联聚合,内存开销更低,适合数据量较大的场景,需要先引入ORM工具类:

from django.db.models import Sum, Subquery, OuterRef, FloatField

# 构造线上销售额的子查询
online_subquery = online_shop.objects.filter(
    sales_date=OuterRef("sales_date"),
    sales_date__range=(fromdate, todate)
).values("sales_date").annotate(
    online_sales=Sum("sales_income")
).values("online_sales")

# 主查询关联子查询,直接生成合并结果
querysetC = store_shop.objects.filter(
    sales_date__range=(fromdate, todate)
).values("sales_date").annotate(
    store_sales=Sum("sales_income"),
    online_sales=Subquery(online_subquery, output_field=FloatField()),
    combine_sales=Sum("sales_income") + Subquery(online_subquery, output_field=FloatField())
).order_by("sales_date")

如果存在某日期仅在线上渠道有销售数据的情况,可先生成覆盖整个查询范围的日期序列作为主表,再分别关联两个渠道的聚合结果即可。

你之前尝试的union()和itertools.chain无法达成效果的原因是,二者都是对查询结果做行级拼接,而非按公共字段sales_date做列级合并,不符合你的需求场景。

内容的提问来源于stack exchange,提问作者James Ho Hon Yan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:42:03