Reputation:
So I have a class called Hero with 150 objects. Each object has a property Winrate. I want to get the top 12 heros based on winrate.
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)
I tried alot of filters but couldn't get it to work.
Upvotes: 0
Views: 589
Reputation: 1145
I would make winrate
an attribute of your Hero class as following.
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)
Then you'll be able to order your request.
super_heroes = Hero.objects.order_by('-winrate')[:12]
EDIT: you shouldn't use len() on a queryset but count() like this:
wins = Match.objects.filter(heros_won=self.pk).count()
Why don't you use the natural primary key instead of this hero_id
?
Upvotes: 1