假设我在django中有这个模型:
class Example(models.Model):
name = models.CharField(max_length=100)
number = models.IntegerField(unique=True)
x = models.FloatField(null=True)
y = models.FloatField(null=True)
z = models.FloatField(null=True)
v = models.FloatField(null=True)
def get_z(self):
z = x / y
self.z = z
self.save()
def get_v(self):
v = z * x
self.v = v
self.save()
当我使用管理面板创建对象时,我只提供名称,数字,x和y字段。我需要z和v字段自动计算对象创建或任何字段更改它们的值。目前它正在制作:
z_value = property(get_z)
并将z_value放在管理面板中的list_display中,然后当我去那里时,会保存值。
答案 0 :(得分:2)
您可以像这样覆盖安全方法:
class Example(models.Model):
...
x = models.FloatField(null=True)
y = models.FloatField(null=True)
z = models.FloatField(null=True)
v = models.FloatField(null=True)
def save(self, *args, **kwargs):
self.z = self.x / self.y
self.v = self.z * self.x
super(Example, self).save(*args, **kwargs)
在保存期间填充字段的原因是它可以使查询更容易。但也有缺点。例如,您必须确保永远不要在这些字段上使用update()
。更新时不会调用save方法!
所以写一个这样的规范化模型可能会更好:
class Example(models.Model):
...
x = models.FloatField(null=True)
y = models.FloatField(null=True)
@property
def z(self):
return self.x / self.y
@property
def v(self):
return self.z * self.x
要在查询集中对z和v执行任何操作,您必须注释字段。像这样:
Example.objects.annotate(z=Sum(F('x') / F('y'))).annotate(v=Sum(F('z') * F('x')))