使用模型方法作为Django Model的默认值?

时间:2016-02-17 15:29:24

标签: python django django-models django-rest-framework

我实际上在我的模型中有这个方法:

var data = JsonConvert.DeserializeObject<dynamic>(jsonString);

我想将它用作我的模型的默认值,如下所示:

data.root.sim:names

但这不起作用(请参阅下面的错误消息)。我已经检查了不同的主题,如this one,但这只适用于函数(不使用def speed_score_compute(self): # Speed score: # # - 8 point for every % of time spent in # high intensity running phase. # - Average Speed in High Intensity # running phase (30km/h = 50 points # 0-15km/h = 15 points ) try: high_intensity_running_ratio = (( (self.h_i_run_time * 100)/self.training_length) * 8) except ZeroDivisionError: return 0 high_intensity_running_ratio = min(50, high_intensity_running_ratio) if self.h_i_average_speed < 15: average_speed_score = 10 else: average_speed_score = self.cross_multiplication( 30, self.h_i_average_speed, 50) final_speed_score = high_intensity_running_ratio + average_speed_score return final_speed_score 属性),但不适用于方法(我必须使用方法,因为我正在处理实际的对象属性)。 / p>

Django doc.似乎在讨论这个问题,但我并不清楚,因为我仍然是Django和Programmation的新手。

有没有办法实现这个目标?

修改

我的功能在我的模型上面定义。但这是我的错误信息:

speed_score = models.IntegerField(default=speed_score_compute)

错误信息很明显,似乎我无法做到这一点。但还有另一种方法可以达到这个目的吗?

1 个答案:

答案 0 :(得分:6)

问题

当我们提供default=callable并从模型中提供方法时,不会使用作​​为模型实例的self参数调用它。

覆盖save()

我还没有找到比覆盖MyModel.save() *更好的解决方案,如下所示:

class MyModel(models.Model):
    def save(self, *args, **kwargs):
        if self.speed_score is None:
            self.speed_score = ...
            # or
            self.calculate_speed_score()

        # Now we call the actual save method
        super(MyModel, self).save(*args, **kwargs)

这使得如果您尝试保存模型而没有该字段的设置值,则会在保存之前填充它。

我个人更喜欢这种方法,即拥有模型中定义的所有模型(数据,方法,验证,默认值等)。我认为这种方法被称为胖Django模型方法

*如果您找到更好的方法,我也想了解它!

使用pre_save信号

Django提供pre_save信号,该信号在模型上运行save()之前运行。信号同步运行,即pre_save代码需要在模型上调用save()之前完成运行。您将获得与覆盖save()相同的结果(以及执行顺序)。

from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import MyModel


@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
    instance = kwargs['instance']
    instance.populate_default_values()

如果您希望将默认值行为与模型分开,则此方法适合您!

何时调用save()?我可以在保存之前使用该对象吗?

好问题!因为我们希望能够在保存填充的默认值之前使用我们的对象。

要获取一个对象而不保存它,只需使用它我们就可以:

instance = MyModel()

如果您使用MyModel.objects.create() 创建,则会调用save()。它基本上(see source code)相当于:

instance = MyModel()
instance.save()

如果您感兴趣,您还可以定义一个MyModel.populate_default_values(),您可以在对象生命周期的任何阶段调用(在创建时,保存时或在de-demande上,它&#39}由你决定)