如何在Django中按客户订单的店铺下单量排序Product QuerySet
Django按指定客户下单最多的店铺排序Product QuerySet
需要获取Product的QuerySet,并按照指定客户订单历史中下单次数最多的店铺排序。例如客户Mike(customer_id=1)在Amazon下单2次、Shopee下单1次,需优先展示Amazon的商品;客户Simon(customer_id=3)仅在Taobao下单1次,需优先展示Taobao的商品。
原代码无法实现预期效果,修正方案如下:
修正后的代码
from django.db.models import Count, Subquery, OuterRef, Coalesce from django.db import models customer_id = 1 # 指定目标客户ID # 子查询:计算每个店铺对应该客户的总下单次数 store_order_counts = Order.objects.filter( customer_id=customer_id, # 关联订单对应商品的店铺ID,与外层Product的store_id匹配 product__store_id=OuterRef('store_id') ).values('product__store_id').annotate( total_orders=Count('id') ).values('total_orders') # 为每个Product标注其所在店铺的该客户下单次数,按次数倒序排序 product_set = Product.objects.annotate( # 用Coalesce处理无订单店铺的空值,默认设为0 store_order_count=Coalesce(Subquery(store_order_counts, output_field=models.IntegerField()), 0) ).order_by('-store_order_count', 'product_name')
原代码问题分析
原代码的核心逻辑错误:
- 原代码中
Count('order__store_id', filter=Q(...))统计的是当前商品自身关联的符合条件的订单数量,而非该商品所在店铺的总订单数量。 - 以Mike的订单为例,Amazon店铺的两个订单分别对应Product1和Product4,原代码会给这两个Product的
count都标注为1,但实际需要它们关联Amazon店铺的总下单次数2。
补充说明
- 追加
product_name作为次要排序条件,可保证相同店铺的商品排序稳定性; - 若不需要处理无订单店铺的空值,可移除
Coalesce,此时无订单店铺的store_order_count会是None,排序时会被放在最后。
内容的提问来源于stack exchange,提问作者PPTing
相关产品推荐
相关产品推荐

