Python 如何筛选Django对象以获得具有最高属性值的前X个对象

Python 如何筛选Django对象以获得具有最高属性值的前X个对象,python,django,class,Python,Django,Class,所以我有一个名为Hero的类,有150个对象。每个对象都有一个属性Winrate。我想根据winrate排名前12名英雄 class Hero(models.Model): hero_name = models.CharField(max_length=20, default = 'Dota 2 Hero') hero_id = models.IntegerField() def __str__(self): return str(self.hero

所以我有一个名为Hero的类,有150个对象。每个对象都有一个属性Winrate。我想根据winrate排名前12名英雄

class Hero(models.Model):

    hero_name = models.CharField(max_length=20, default = 'Dota 2 Hero') 
    hero_id = models.IntegerField()

    def __str__(self):
        return str(self.hero_id)
    def get_winrate(self):
        wins = len(Match.objects.filter(heros_won = Hero.objects.get(hero_id = self.hero_id)))
        losses = len(Match.objects.filter(heros_lost  = Hero.objects.get(hero_id = self.hero_id)))
        if wins + losses != 0:
            return round((wins / (wins + losses)),2)
        else:
            return 0 
    winrate = property(get_winrate)

我尝试了很多过滤器,但都无法使用。

我会将
winrate
作为英雄类的属性,如下所示

class Hero(models.Model):

    hero_name = models.CharField(max_length=20, default = 'Dota 2 Hero') 
    hero_id = models.IntegerField()
    winrate = models.IntegerField()

    def _get_winrate(self):
        wins = len(Match.objects.filter(heros_won = Hero.objects.get(hero_id = self.hero_id)))
        losses = len(Match.objects.filter(heros_lost  = Hero.objects.get(hero_id = self.hero_id)))
        if wins + losses != 0:
            return round((wins / (wins + losses)),2)
        else:
            return 0 

    def save(*args, **kwargs):
        self.winrate = self._getwinrate()
        return super().save(*args, **kwargs)
然后你就可以按要求订购了

super_heroes = Hero.objects.order_by('-winrate')[:12]
编辑:您不应该在查询集上使用len(),而应该像这样使用count()

wins = Match.objects.filter(heros_won=self.pk).count()

为什么不使用自然主键而不是此
英雄id

我建议您将获胜率添加为模型的属性。然后,您可以使用排序查询来获取所需内容。根据现在的情况,您必须使用对数据库中每个对象的多个查询来计算获胜率,在表中的所有行上,以获得前12名。我将获胜率作为属性,不是吗
winrate=property(get_winrate)
这样做是否允许您在
winrate
字段上使用排序查询?def save(*args,**kwargs)`self.winrate=self.\u getwinrate()返回super().save(*args,**kwargs)`在这里做什么?这很明显。每次保存实例时,它都会在每次保存时更新实例。顺便说一句,我已经编辑了我的文章。