Django: 如何通过模型方法设置默认字段值

3
最初的回答:
我有一个简单的模型。我想基于同一模型中的某些字段(我们称其为分数)计算其一个字段的默认值。
我的理想方式是这样的:
class ModelA(models.model):
    field_1 = models.IntegerField()
    field_1 = models.IntegerField()
    score = models.IntegerField(default=self.calculate_default())

    def calculate_default(self):
        default = (self.field_1 + self.field_2) / 2
        return default
问题:calculate_default方法无法访问self。 我尝试的一个解决方案是覆盖save()方法。问题是它会阻止用户进一步更改score字段。
另一种我搜索到的方法是覆盖类的inti。但根据django的说法,如果实现不正确可能会产生后果。
如何最简洁地实现此目标?如何设置字段的默认值,使其从同一模型的其他字段计算出来,以便稍后可以由用户更改?
我有一种预感classmethod是正确的方法,但我还没有成功实现。

默认值不能是一个带有self参数的可调用对象。default=...应该是一个没有参数的可调用对象或者一个值。 - Willem Van Onsem
不要使用default来做那个。而是将计算添加到模型的save()方法中。 - dirkgroten
1个回答

3
"最初的回答"翻译成中文为:"Original Answer"
计算默认方法无法访问self。我尝试过的一个解决方案是覆盖save()方法。但问题是它会阻止用户进一步更改得分字段。
实际上,这是正确的方法。但您可以在save()方法中添加一个检查,以检查score的值是否为空:
def save(self, *args, **kwargs):
    if self.score == None:
       self.score = self.calculate_default()
    super().save(*args, **kwargs)

顺便说一下,在classmethod中,您无法访问selfModelA对象。 如果您打算使用的类方法与ModelA实例的字段无关或完全独立(例如:当前日期datetime.now),则可以使用该方法。


1
这个看起来很合理,但对我来说并没有起作用。原因是你的示例中有一个拼写错误:"scrore" -> score。现在已经修正了。 - Amir Afianian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接