我想知道Django queryset中的排名

时间:2018-08-20 09:26:01

标签: mysql django

我有一个产品列表模型,想知道该模型特定价格的排名。

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

还有其他解决方法吗?

1 个答案:

答案 0 :(得分:2)

我们可以通过CountProduct的数量设置为更高 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

因此,在我们没有找到乘积的情况下,我们会不断递增,以防万一,我们停止迭代并获得了排名。