Django calculation based on calculated value

时间:2017-08-05 12:23:50

标签: python django django-models django-admin

I need your help once more. I am working on a project for my wargaming group. It is a simple ranking site. So we have players, they participate in tournaments and get points. I got to the point where I am able to assign players to tournaments, assign place they took at the tournament to their name.

Now I have to calculate points. Algorithm is simple, but I have problems passing a value from Tournament model to Ranking. Each Tournament has a calculated rating (based on other things, mostly bigger tournament, bigger rating) and in other models, I was unable to use it and need your help with it. On top of that, it would be awesome if changing a rating value in Tournament would force an update of all dependent calculations.

So we have models like that:

 class Player(models.Model):
    class Meta:
    name = models.CharField(max_length=50)
    nicname = models.CharField(max_length=50,blank=True)
    army = models.CharField(max_length=50)
    def __unicode__(self):
        return self.name
    def __str__(self):
        return self.name

class Tournament(models.Model):
    class Meta:
    name = models.CharField(max_length=100)
    date = models.DateTimeField('date')
    player_num = models.IntegerField
    points = models.FloatField(default=1000.00)


    def __unicode__(self):
        return self.name
    def __str__(self):
        return self.name

And then I have a ranking model of this kind:

class TournamentStandings(models.Model):
    tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE)
    player = models.ForeignKey(Player, on_delete=models.CASCADE)
    player_place = models.FloatField

In admin.py I do calculations for TournamentAdmin:

fields = ['name', 'date', 'player_num', 'points', 'get_rating']
def get_rating(self, obj):
    return obj.points / 100.00

And now I would like to make calculation for TournamentStandingsAdmin:

def player_points(self, obj):
    return (obj.tournament.player_num/obj.player_place)* obj.tournament.get_rating

But the result is an error

'Tournament' object has no attribute 'get_rating'

So my guess is my calculated get_rating is not a true model field but how to work around that?

1 个答案:

答案 0 :(得分:2)

正如@Daniel建议您需要将get_rating方法添加到Tournament模型中。

class Tournament(models.Model):
    name = models.CharField(max_length=100)
    date = models.DateTimeField('date')
    player_num = models.IntegerField
    points = models.FloatField(default=1000.00)

    ....
    def get_rating(self):
        return obj.points / 100.00

之后,您可以使用Tournament对象调用该方法,如下所示:

obj.tournament.get_rating