【问题标题】:Save calculated value as a model field将计算值保存为模型字段
【发布时间】:2017-12-07 22:35:05
【问题描述】:

作为我之前的question 的后续行动,我有了一个新的。如何将此计算值保存为模型字段。我想在我的视图和模板中使用它来按此字段排序列表。

我的模型:

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

有趣的是,在管理员列表中,我有一列 player_points 计算正确,但是当我添加一个新模型实例并尝试保存它时,我收到此错误:'TournamentStandings' object has no attribute 'get_player_points'。是不是因为我正在尝试进行“自我”保存而我的计算是 (self, obj) ?欢迎任何提示。

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    get_player_points() 是一个方法,需要括号。

    def save(self, *args, **kwargs):
         self.player_points = self.get_player_points() 
    

    【讨论】:

    • 现在我有了这个:get_player_points() takes exactly 2 arguments (1 given)
    • 是的。你写了 get_player_points 来接受 2 个参数:self 和 obj。 Self 是自动传递的,但您需要传递一个有效的 obj 参数或更改您的代码,使其不需要第二个参数。
    • 我怀疑您实际上想删除 obj 作为参数并在方法中使用 obj 的所有地方使用 self 。 return self.tournament.player_num * self.tournament.get_rating() -self.tournament.get_rating()*(self.player_place - 1.00)
    • 我想我必须重新工作更多。按照您的建议完成后,我得到了这个:global name 'tournament' is not defined
    • 用这个想法进行更多测试 - 如果我跳过“obj”,我最终会得到一个未知的锦标赛字段实例。我必须通过一个信息女巫'get_rating'你使用。
    【解决方案2】:

    针对我的问题发布一个可行的解决方案。不需要括号。

    首先我修复了锦标赛模型,所以我可以将get_rating 保存为字段:

    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
    

    当我有这个时,我试图将它复制到第二个模型。问题是我无法让它工作,因为我在计算中调用了相关的 obj。但!我已设法将此值分配给 get_player_points 内的变量,现在一切都按预期工作:

    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
    

    这行得通!欢迎提出任何关于我可以改进的想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-15
      • 2021-10-28
      • 2020-10-07
      • 2015-05-12
      相关资源
      最近更新 更多