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

如何通过Django QuerySet按销量排序获取Top10畅销商品

问题描述

需要从分属不同应用的模型中获取销量Top10的商品,现有模型结构如下:

Product模型

class Product(models.Model):
   user = models.ForeignKey(Vendor, on_delete=models.CASCADE)
   category = models.ForeignKey(Category, on_delete=models.CASCADE)
   ubcategory = models.ForeignKey(SubCategory, on_delete=models.CASCADE, blank=True, null=True)
   product_name = models.CharField(max_length=100)
   product_slug = models.SlugField(max_length=100, unique=True)

SoldProduct模型(记录已售商品)

class SoldProduct(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='soldproducts')
    quantity = models.IntegerField()

目前已通过以下QuerySet获取商品PK和销量总和:

best_seller_products = SoldProduct.objects.filter(product__in=products, order__in=orders).values(
  'product__pk',).annotate(qty=Sum('quantity')).order_by('-qty')[:6]

查询结果示例:

<QuerySet [{'product__pk': 5, 'qty': 22}, {'product__pk': 6, 'qty': 6}]>

随后通过PK获取商品列表:

best_seller_products = products.filter(pk__in=list_best_seller_products_pk)

需要解决的问题:如何将该商品列表按对应销量排序?优先采用查询方式,不在Product模型新增sold字段。

解决方案

方案一:数据库层面直接查询并排序(优先推荐)

直接从Product模型出发,通过反向关联(soldproducts是SoldProduct中定义的related_name)筛选符合条件的商品,同时标注总销量并排序,一步到位得到已按销量排序的Product实例集合:

best_seller_products = Product.objects.filter(
    pk__in=products,  # 保留你原本的Product筛选范围
    soldproducts__order__in=orders  # 关联订单筛选条件
).annotate(
    total_sales=Sum('soldproducts__quantity')
).order_by('-total_sales')[:10]  # 按总销量倒序,取Top10

优势

  • 数据库层面完成筛选、统计和排序,性能更优,尤其适合数据量较大的场景
  • 直接返回排序后的Product实例,无需后续内存中二次处理

方案二:内存中基于销量映射排序(兼容现有两步查询逻辑)

如果必须保留先获取销量PK映射、再查询商品的逻辑,可以将销量数据转成字典,用Pythonsorted函数完成排序:

# 第一步:获取商品PK与销量的映射字典
sales_map = {item['product__pk']: item['qty'] for item in best_seller_products}

# 第二步:查询商品并按销量排序
sorted_products = sorted(
    products.filter(pk__in=sales_map.keys()),
    key=lambda product: sales_map[product.pk],
    reverse=True  # 倒序排列,销量高的在前
)

说明

  • 适合无法修改初始查询逻辑的场景,但数据量大时内存排序效率不如数据库层面处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 00:13:10