Django-как аннотировать QuerySet, используя несколько значений полей?


У меня есть модель под названием "История", которая имеет два целочисленных поля под названием "мнения" и "голоса". Когда я получаю все объекты истории, я хотел бы аннотировать возвращенный QuerySet полем "Рейтинг", которое просто"просмотры"/"голоса". Затем я хотел бы отсортировать QuerySet по "ранжированию". Что-то вроде этого...

Story.objects.annotate( ranking=CalcRanking('views','votes') ).sort_by(ranking)

Как я могу сделать это в Django? Или это должно быть сделано после извлечения QuerySet в Python (например, создание списка, содержащего ранжирование для каждого объекта в QuerySet)?

Спасибо!

PS: в моей реальной программе расчет ранжирования не так прост, как выше, и зависит от других фильтров к исходному набору запросов, поэтому я не могу хранить его как другое поле в модели истории.

1 2

1 ответ:

В Django вещи, которые вы можете передать в annotateaggregate), должны быть подклассами django.db.models.aggregates.Aggregate. Вы не можете просто передать ему произвольные объекты Python, так как агрегация / аннотация фактически происходит внутри базы данных (в этом весь смысл aggregate и annotate). Обратите внимание, что написание пользовательских агрегатов не поддерживается в Django (для этого нет документации). Вся информация, доступная на нем - это этот минимальный исходный код: https://code.djangoproject.com/browser/django/trunk/django/db/models/aggregates.py

Это означает, что вам нужно либо каким-то образом сохранить вычисления в базе данных, выяснить, как работает aggregation API, либо использовать raw sql (методraw в менеджере), чтобы сделать то, что вы делаете.