Django QuerySet是否用prefetch?分组统计商品及数量问题求助
解决商品按分类分组并获取符合条件商品数量及列表的问题
嗨,这个场景我之前做电商项目时刚好碰到过,咱们来一步步搞定它~
首先明确你的核心需求:筛选出包含价格≥100商品的分类,同时获取每个分类下符合条件的商品数量和具体商品列表。你之前的QuerySet只拿到分类,是因为没做好商品子集的关联和统计,这时候确实需要用到prefetch_related,但得配合Prefetch对象精准控制预取的商品范围,而不是用默认的预取逻辑。
具体实现步骤
导入必要的模型和工具
先把需要的模块导入进来:from django.db.models import Prefetch, Count, Q from yourapp.models import Category, Product # 替换成你的实际模型名定义符合条件的商品子集QuerySet
先单独筛选出价格≥100的商品,后续会用到这个QuerySet:qualified_products = Product.objects.filter(price__gte=100)查询分类并关联商品数据
这一步是关键,我们要同时完成:筛选目标分类、统计符合条件的商品数量、预取对应的商品列表:categories_with_products = Category.objects.filter( # 先筛选出至少有一个符合条件商品的分类 product__price__gte=100 ).annotate( # 统计每个分类下价格≥100的商品数量,用filter参数精准统计 qualified_product_count=Count('product', filter=Q(product__price__gte=100)) ).prefetch_related( # 用Prefetch指定预取的是我们之前筛选好的商品子集,并存到自定义属性里 Prefetch('product_set', queryset=qualified_products, to_attr='qualified_products_list') ).distinct() # 去重,避免同一个分类因多个符合条件商品被重复返回
代码解释
filter(product__price__gte=100):确保只返回存在符合条件商品的分类,和你之前的效果一致,但我们在此基础上扩展了统计和预取逻辑。annotate(qualified_product_count=...):用Count配合filter参数,只统计每个分类中价格≥100的商品数量,而不是该分类下的所有商品数量。Prefetch(...):这是核心!默认的prefetch_related('product_set')会拉取分类下的所有商品,而我们用Prefetch指定只预取之前筛选好的qualified_products,并把这些商品存到qualified_products_list属性中,方便后续直接调用。distinct():因为一个分类下可能有多个符合条件的商品,原始查询会返回多次同一个分类,所以用distinct()去重,保证每个分类只出现一次。
使用示例
拿到结果后,你可以直接遍历获取需要的数据:
for category in categories_with_products: print(f"分类名称:{category.name}") print(f"符合条件的商品数量:{category.qualified_product_count}") print("商品列表:") for product in category.qualified_products_list: print(f"- 商品名:{product.name},价格:{product.price}")
这样就能完美实现你要的需求:既拿到了符合条件的分类,又能直接获取每个分类下的商品数量和具体商品列表,而且数据库查询次数最少,性能最优。
内容的提问来源于stack exchange,提问作者user7515195
相关产品推荐
相关产品推荐

