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

如何用Django QuerySet简化查询:获取3个类别各最低价产品

一次查询获取指定类别下的最低价产品

嘿,我来帮你把这三次重复的查询合并成一次高效的数据库请求,这样能减少数据库往返次数,提升性能!

核心思路

我们可以利用Django的Subquery和OuterRef来实现:先定义一个子查询,用来获取每个类别下价格最低的产品,然后在查询指定类别时,通过annotate把这个子查询的结果关联到每个类别对象上。

具体实现代码

假设你的Product模型和Category模型的关联是通过外键,且related_name为category_product(和你原来的代码一致),那可以这么写:

from django.db.models import Subquery, OuterRef

# 1. 定义子查询:获取当前类别下价格最低的第一个产品(按价格升序排序)
lowest_product_subquery = Product.objects.filter(
    category=OuterRef('pk')  # 关联外部查询的Category主键
).order_by('price')[:1]  # 取价格最低的第一个产品

# 2. 一次性查询ID为1、2、3的类别,并标注每个类别的最低价产品信息
target_categories = Category.objects.filter(
    id__in=[1, 2, 3]
).annotate(
    # 按需标注你需要的产品字段,比如价格、名称、ID
    lowest_product_price=Subquery(lowest_product_subquery.values('price')[:1]),
    lowest_product_name=Subquery(lowest_product_subquery.values('name')[:1]),
    lowest_product_id=Subquery(lowest_product_subquery.values('id')[:1])
)

如何使用结果

现在target_categories是一个QuerySet,每个类别对象都带有我们标注的最低价产品属性,你可以直接遍历使用:

for category in target_categories:
    print(f"类别 [{category.id}] {category.name}:")
    print(f"  最低价产品:ID {category.lowest_product_id},名称 {category.lowest_product_name},价格 {category.lowest_product_price}")

注意事项

  • 如果某个类别下没有产品,对应的lowest_product_*属性会是None,使用时可以做个判断避免报错。
  • 这个方法只发送一次数据库请求,相比原来的三次查询,性能提升很明显,尤其是当需要查询的类别数量更多时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:10:35