Reputation: 161
As a follow up to my eariler question I have a new one. How can I save this calculated value as a model field. I would like to use it in my views and templates to order list by this field.
My models:
class Tournament(models.Model):
name = models.CharField(max_length=100)
date = models.DateTimeField('date')
player_num = models.IntegerField(verbose_name="")
points = models.FloatField(default=1000.00)
def get_rating(self):
return self.points / 1000.00
class TournamentStandings(models.Model):
tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE)
player = models.ForeignKey(Player, on_delete=models.CASCADE)
player_place = models.FloatField(verbose_name=u"")
player_points = models.FloatField(verbose_name="",
blank=True) #added for testing to save the calculated value in it
@property
def get_player_points(self, obj):
return obj.tournament.player_num * obj.tournament.get_rating() -
obj.tournament.get_rating()*(obj.player_place - 1.00)
def save(self, *args, **kwargs):
self.player_points = self.get_player_points
super(TournamentStandings, self).save(*args, **kwargs)
def __float__(self):
return self.player_points
Funny as on the admin list I have a column where player_points
are calculated correctly but when I add a new model instance and try to save it I get this error : 'TournamentStandings' object has no attribute 'get_player_points'
. Is it bacause I am trying to do a "self" save and my calculation is (self, obj) ?? Any hints are wellcome.
Upvotes: 1
Views: 3192
Reputation: 161
Posting a working solution to my problem. No need for parentheses.
First I have fixed Tournament model, so I could save get_rating
as a field:
class Tournament(models.Model):
name = models.CharField(max_length=100)
rating = models.FloatField(verbose_name="Rating", blank=True)
@property
def get_rating(self):
return (self.points) / (1000.00)
def save(self, *args, **kwargs):
self.rating = self.get_rating
super(Tournament, self).save(*args, **kwargs)
def __float__(self):
return self.rating
When I had this I tried to copy it to second model. Problem was that I could not get it to work due to related obj I was calling in my calculation. But! I have managed to assign this values to variables inside get_player_points
and now all is working as intended:
class TournamentStandings(models.Model):
tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE)
player = models.ForeignKey(Player, on_delete=models.CASCADE)
player_place = models.FloatField(verbose_name="")
player_points = models.FloatField(verbose_name="", blank=True)
@property
def get_player_points(self):
player_num = float(self.tournament.player_num)
rating = float(self.tournament.rating)
player_points = float(rating*player_num-rating*(self.player_place - 1.00))
return player_points
def save(self, *args, **kwargs):
self.player_points = self.get_player_points
super(TournamentStandings, self).save(*args, **kwargs)
def __float__(self):
return self.player_points
And this works! Any thoughts on improvements I could make are wellcome ofc.
Upvotes: 1
Reputation: 697
get_player_points() is a method and requires parentheses.
def save(self, *args, **kwargs):
self.player_points = self.get_player_points()
Upvotes: 0