1

私はリーグシステムを書いていて、そのシーズン中に各プレイヤーが獲得したポイントでソートされた各シーズンのプレイヤーランキングを表示したいと考えています。

これまでのところ、次のようなコードでそれを行うことができました:

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() を使用できると思います。

4

2 に答える 2