Нахождение позиции определенной записи в запросе в DJango ORM

У меня есть такая модель Django,

class Account(models.Model):
    user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=255, null=True)
    ratings = models.FloatField(default=1000)

Что я хочу сделать - это человек, который вошел в систему, я хочу найти его rank на основе рейтинга пользователя. То есть, мне нужно найти позицию указанной строки в запросе, где записи будут упорядочены по колонке ratings, в порядке убывания.

Я нашел хорошее решение здесь, но оно, к сожалению, не работает для меня. https://stackoverflow.com/a/51317266/11454905

Используя эту же концепцию, я набрал следующий запрос,

player = Account.objects.filter(user = request.user).annotate(rank = Window(expression=Rank(), order_by=F('ratings').desc()),)[0]

Но независимо от того, какой пользователь, он всегда возвращает player.rank как 1, что не соответствует действительности. Я не могу понять, что я делаю неправильно и как я могу это исправить.

Если вы делаете это только для одного объекта User, то вы можете просто подсчитать пользователей, у которых рейтинг выше, чем у текущего пользователя - я заметил, что вы используете filter(user=request.user), который на самом деле не получает объект одного пользователя. Вообще говоря, вы должны использовать get(), хотя здесь вы можете просто сделать request.user.

rank = Player.objects.filter(ratings__gte=request.user.ratings).count()

Что касается аннотирования набора пользователей, можно использовать выражения Window() и DenseRank():

from django.db.models import Window
from django.db.models.functions import DenseRank

players = Player.objects.order_by('ratings').annotate(
    rank=Window(
        expression=DenseRank(),
        order_by=F('ratings').desc()
    )
)
Вернуться на верх