我正在编写一个联赛系统,我想显示每个赛季的球员排名,按每个球员在该赛季累积的积分排序。
到目前为止,我设法使用类似于以下的代码来做到这一点:
class Player(models.Model):
name = models.CharField(max_length=100)
class Season(models.Model):
name = models.CharField(max_length=100)
start_date = models.DateField()
end_date = models.DateField()
players = models.ManyToManyField(Player)
def get_player_rank(self, player):
return player.matchresult_set.filter(season=self).aggregate(points=Sum('points'))['points']
def get_ranks(self):
ranks = [(player, self.get_player_rank(player)) for player in self.players.all()]
ranks.sort(key=lambda tup: tup[1])
return ranks
class Match(models.Model):
date = models.DateField()
players = models.ManyToManyField(Player, through='MatchResult')
season = models.ForeignKey(Season)
class MatchResult(models.Model):
player = models.ForeignKey(Player)
match = models.ForeignKey(Match)
points = models.IntegerField()
我认为同样可以通过更简单的聚合来实现,但我就是无法正确使用 annotate()。
我试过这个,但它只是总结了整个赛季的所有点:
class Season(models.Model):
def get_ranks(self):
return self.players.annotate(points=Sum('matchresult__points')).order_by('-points')
我错过了什么?我猜如果 .extra() 会导致可移植代码,则可以使用它。