我有一个产品列表模型,想知道该模型特定价格的排名。
sorted_product_list = Product.objects.all().order_by('-price')
my_product = {'id': 10, 'price': 20000}
django具有RowNum
类,但不支持mysql
我只有一个使用enumerate
for rank, element in enumerate(sorted_product_list):
if element.id == my_product.id:
my_product_rank = rank
还有其他解决方法吗?
答案 0 :(得分:2)
我们可以通过Count
将Product
的数量设置为更高 price
来获得 rank 那将是第一个),所以:
rank = Product.objects.filter(price__gt=myproduct['price']).count()
或者如果我们不预先知道价格,我们可以先获取价格:
actual_price = Product.objects.values_list('price', flat=True).get(id=myproduct['id'])
rank = Product.objects.filter(price__gt=actual_price).count()
因此,我们不必“生成”表,而是可以过滤该行上方的行数并对其进行计数。
请注意,如果多个 Product
的价格为相同,我们将在这些Product
中以最小的排名为排名。因此,如果有四个产品的价格分别为$ 200,$ 100,$ 100和$ 50,则价格为$ 100的两个Product
的排名将为1
。费用为$ 50的Product
的排名为3
。从某种意义上说,这是合乎逻辑的,因为这些产品之间没有“内部等级”:数据库可以自由地以其想要的任何方式退还这些产品。
鉴于price
列上有一个索引(它是一个二叉树),这应该可以很快地工作。因此查询将不从数据库中获取元素。
如果内部排名 很重要,我们可以使用一种方法,首先确定“ 外部排名”,然后遍历Product
以相同的价格确定“ 内部排名”,但是请注意,这没有多大意义,因为在两次查询之间,这种“内部顺序”可能会发生变化:
# rank that also takes into account *equal* prices, but *unstable*
actual_price = Product.objects.values_list('price', flat=True).get(id=myproduct['id'])
rank = Product.objects.filter(price__gt=actual_price).count()
for p in Product.objects.filter(price=actual_price):
if p.id != myproduct['id']:
rank += 1
else:
break
因此,在我们没有找到乘积的情况下,我们会不断递增,以防万一,我们停止迭代并获得了排名。