Big*_*oke 2 python sql sqlite django django-models
我正在尝试根据在许多比赛中获得的积分为球队分配排名。得分更高的球队排名更高,如果得分相等,则比赛次数最少的球队排名更高。团队可以拥有同等的排名。
因为Django(也不是SQLite)支持DENSE_RANK
window函数,所以我必须在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)
Run Code Online (Sandbox Code Playgroud)
这是行不通的,因为Django的ORM 在其中的“表名”周围添加了双引号extra(table)
还有其他方法可以将文字值添加到预先存在的QuerySet
,还是我必须用的调用替换要注释的调用raw()
,然后从那里开始工作?太可惜了,因为我花了相当多的时间来理解如何将原始的原始SQL查询(使用GROUP BY
s和所有东西)转换成更像Django的工作方式。我很乐意使用Django,而不是跳到我自己的旧SQL调子上。
您可以使用Value添加文字值:
qs = self.model.objects.annotate(
num_games=Count('team__score_set'),
total_points=Sum('team__score_set__points'),
ranking=Value(42, output_field=IntegerField())
).order_by('-total_points')
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1024 次 |
最近记录: |