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

DRF ORM单查询实现商户商品销量统计及关联ID获取

Django ORM单查询实现商户-商品销售总量统计

已知模型定义

class Merchant(BaseModel):
    business_name = CharField()
    user = ForeignKey(
        User,
        related_name='merchant'
        # 其他参数...
    )
    # 其他字段...


class Sale(BaseModel):
    merchant = ForeignKey(
        Merchant,
        related_name='sale_merchant'
        # 其他参数...
    )
    status = CustomCharField(  # 修正原拼写错误statue→status
        max_length=20,
        choices=[(DRAFT, DRAFT), (COMPLETED, COMPLETED), (FAILED, FAILED)],  # 修正括号错误
        # 其他参数...
    )
    # 其他字段如total、discount、date...


class SaleItem(BaseModel):
    quantity = PositiveIntegerField()
    product = ForeignKey(
        Product,
        # 其他参数...
    )
    sale = ForeignKey(
        Sale,
        related_name='sold_item'
        # 其他参数...
    )
    # 其他字段...

补充:Product模型包含商品名称字段,User模型关联City模型存储用户所属城市

需求说明

通过单条DRF ORM查询,获取每个商户各商品的销售总量,输出字段需包含:

  • id:该商户-商品组合对应的首个SaleItem记录ID
  • Merchant Name:商户名称(Merchant.business_name)
  • Denomination:商品名称(Product.name)
  • Quantity:该商户对应商品的销售总数量
  • Merchant City:商户所在城市(User.city.name)

单查询实现方案

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

# 子查询:获取每个商户-商品组合的首个SaleItem ID
first_sale_item_subquery = SaleItem.objects.filter(
    sale__merchant=OuterRef('sale__merchant'),
    product=OuterRef('product')
).order_by('id').values('id')[:1]

# 主查询:分组统计销售总量并关联所需字段
queryset = SaleItem.objects.filter(
    sale__status=COMPLETED  # 可选:仅统计已完成的订单,根据业务需求调整
).values(
    # 分组维度:商户+商品
    'sale__merchant__id',
    'sale__merchant__business_name',
    'product__name',
    'sale__merchant__user__city__name'
).annotate(
    total_quantity=Sum('quantity'),
    first_sale_item_id=Subquery(first_sale_item_subquery)
).order_by(
    'sale__merchant__business_name',
    'product__name'
)

查询结果映射

将查询结果转换为需求格式的示例:

idMerchant NameDenominationQuantityMerchant City
1Merchant_1Product_1133London
2Merchant_1Product_21234NYC
3Merchant_2Product_154Tokyo

关于id字段的优化建议

如果仅需要获取该商户-商品的销售项信息,无需依赖首个SaleItem的ID,直接通过商户ID+商品ID组合查询更高效:

# 示例:查询Merchant_1的Product_1所有销售项
sale_items = SaleItem.objects.filter(
    sale__merchant__business_name='Merchant_1',
    product__name='Product_1'
)

这种方式避免了子查询的额外开销,且定位逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:35:10