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

Django ORM如何获取每个商品的最高价格及对应日期

解决方法

要获取每个商品的最高价格及对应日期,可以通过Django的Subquery和OuterRef实现,这是符合ORM规范的常用方式,适用于Django 2.0及以上版本:

步骤1:导入必要模块

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

步骤2:编写查询代码

# 子查询1:获取每个商品对应的最高价格
max_price_subquery = Price.objects.filter(
    product=OuterRef('pk')
).values('product').annotate(
    max_price=Max('price')
).values('max_price')

# 子查询2:根据最高价格匹配对应的日期
max_date_subquery = Price.objects.filter(
    product=OuterRef('pk'),
    price=OuterRef('max_price')
).values('date_seen')[:1]  # 取第一条记录,避免同商品同价格多条记录的干扰

# 最终查询:为每个商品标注最高价格和对应日期
result = Product.objects.annotate(
    max_price=Subquery(max_price_subquery),
    max_price_date=Subquery(max_date_subquery)
).values(
    'title', 'name', 'max_price', 'max_price_date'
)

结果说明

  • 执行后result是一个QuerySet,每个元素是包含商品标题、名称、最高价格、对应日期的字典
  • 若商品无价格记录,max_price和max_price_date会返回None

简化方案(无重复最高价场景)

如果业务中每个商品的最高价格仅出现一次,也可以用Prefetch预加载关联记录:

from django.db.models import Max, Prefetch

# 先获取每个商品的最高价格映射
product_max_prices = Price.objects.values('product').annotate(max_p=Max('price'))
max_price_map = {item['product']: item['max_p'] for item in product_max_prices}

# 自定义预加载查询,只获取每个商品的最高价记录
prefetch_max_price = Prefetch(
    'price_set',
    queryset=Price.objects.filter(
        product__in=max_price_map.keys(),
        price=Subquery(Price.objects.filter(product=OuterRef('pk')).values('product').annotate(m=Max('price')).values('m')[:1])
    ),
    to_attr='max_price_record'
)

products = Product.objects.prefetch_related(prefetch_max_price).all()

# 遍历提取数据
for product in products:
    if product.max_price_record:
        print(f"{product.title} 最高价: {product.max_price_record[0].price},日期: {product.max_price_record[0].date_seen}")

注意事项

  • 你的模型代码中Class需改为小写class,符合Python语法规范
  • 若存在同一商品同一天多条相同最高价记录,[:1]会取最早的那条,需全部记录可去掉切片

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:17:19