简体   繁体   English

如何在Django中按模型功能排序

[英]how to order by model function in django

I have the following model: 我有以下模型:

class Player(models.Model):
    user = models.OneToOneField(User, related_name="player")
    first_name = models.CharField(max_length=128)
    last_name = models.CharField(max_length=128)

    def point_total(self):
        playerAchievements = PlayerAchievement.objects.filter(player=self)
        score = 0
        for p in playerAchievements:
            score += p.achievement.value
        return score

    def full_name(self):
        return self.first_name + ' ' + self.last_name

    def rank(self):
        print '---'
        players = Player.objects.filter(team__league=self.team.league).order_by(self.point_total())
        print self.first_name
        position = 0
        for p in players:
            position +=1

            if p.id == self.id:
                return str(position)
        return '0'

Nothing is processed past this line: 超出此行的任何处理:

players = Player.objects.filter(team__league=self.team.league).order_by(self.point_total())

I also tried this but has the same effect: 我也尝试过此方法,但具有相同的效果:

players = self.objects.filter(team__league=self.team.league).order_by('player__point_total')

How can I order by the point total function so I can figure out the rank of each player? 如何按积分功能排序,以便确定每个玩家的排名?

The order_by function only operates on fields in the database, so calling a function won't work. order_by函数仅对数据库中的字段起作用,因此调用该函数将无效。

What you can do however is annotate the function with a Count aggregation across the ForeignKey and then order_by that: 但是,您可以执行的操作是在ForeignKey上使用Count聚合对函数进行注释 ,然后在order_by上进行注释

from django.db.models import Sum

players = Player.objects.filter(team__league=self.team.league)
players = players.annotate(achievement_sum=Sum('playerachievement_set__achievement__value'))
players = players.order_by('achievement_sum')

You can't order querysets by methods and properties in django, you have to do the sorting by yourself in python. 您无法在Django中按方法和属性对查询集进行排序,而必须在python中自行进行排序。

players_to_sort = Player.objects.filter(team__league=self.team.league)
sorted_player = sorted(players_to_sort, key=lambda player: player.point_total() )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM