Я пытаюсь присвоить звание командам на основе очков, полученных за несколько игр. Команда с большим количеством очков занимает больше места, и если команды имеют равное количество очков, команда с наименьшими играемыми играми занимает больше места. Команды могут иметь равный ранг.Добавление литеральных значений в QuerySet в Django
Поскольку Django (или SQLite) поддерживает функцию окна DENSE_RANK
, я должен вычислить ранг в Python. Хотя, первоначально, я сделал это на экземплярах модели, возвращаемых all()
, я решил, что должен добавить ранг в QuerySet
, возвращенный annotate().order_by()
, сохраняя при этом объект QuerySet
, например, с get()
.
class TeamManager(models.manager):
@staticmethod
def add_ranking(qs):
# First, populate rows and rankings lists
# ...
# Then, add it to the query set
literal_selects = []
for row_id, ranking in zip([row.id for row in rows], rankings):
literal_selects.append('SELECT {} AS "thing_id", {} AS ranking'.format(row_id, ranking))
extra_from = "(" + " UNION ALL ".join(literal_selects) + ")"
return qs.extra(
tables=[extra_from],
select={'ranking': 'ranking'},
where=['team.id = thing_id'])
def ranked_list(self):
qs = self.model.objects.annotate(
num_games=Count('team__score_set'),
total_points=Sum('team__score_set__points'),
# Ideally, I would calculate ranking here
).order_by('-total_points')
return TeamManager.add_ranking(qs)
Это не работает, потому что ORM Джанго adds double quotes вокруг «имен таблиц» в extra(table)
Есть ли другой способ добавить буквенные значения к уже существующей QuerySet
, или я должен заменить вызов аннотировать с вызовом на raw()
, а затем работать оттуда? Было бы очень жаль, потому что я только что вложил немалый кусок времени в понимание того, как перевести исходный необработанный SQL-запрос (с GROUP BY
и все) в более удобный для Djangoeque способ делать вещи. Я бы хотел, чтобы Django выбрался из этого, вместо того, чтобы танцевать в моей собственной старой мелодии SQL.
Неа, я думаю, вы должны использовать 'raw' ... более вариант«там»будет испечь этот запрос в вид, который может быть представлен как отдельная модель через http://django-postgres.readthedocs.org/en/latest/views.html – Anentropic
Не настоящий ответ, но когда мне приходилось сталкиваться с подобными проблемами при расчете ранжирования, я закончил создание другой стол с «очками/баллами». Он также сделал запрос намного быстрее, когда мы зацикливались на некоторых больших таблицах. Поэтому, возможно, есть способ создать и использовать какую-то таблицу «заработанных очков». – WayBehind
Опубликуйте свои models.py – schillingt