我有以下模型:
class MeasurementParameter(models.Model):
tolerance = models.FloatField()
set_value = models.FloatField()
tol_low = None
tol_high = None
def tolerance_band(self):
tol = self.set_value * self.tolerance/100
self.tol_high = self.set_value + tol
self.tol_low = self.set_value - tol
print self.tol_low
return self.tol_high, self.tol_low
我希望使用tolerance_band方法将计算出的局部变量设置为tol_low和tol_high。
该模型与另一个名为Product的模型具有ManyToMany关系。
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
parameters = models.ManyToManyField(MeasurementParameter, related_name='measurement')
def calc_all_tol_bands(self):
for parameter in self.parameters.all():
hi, lo = parameter.tolerance_band()
def __str__(self):
return self.name
所以在我看来,我尝试通过以下方式计算所有公差带:
product.calc_all_tol_bands()
但是,如果我尝试获取局部变量:
product.parameters.all()[0].tol_low
我一直都没有。
要在MeasurementParameter模型中设置计算值,我需要做什么?
约翰。
答案 0 :(得分:1)
这是预期的行为。评估时
product.parameters.all()[0]
这意味着您进行数据库提取。因此,Django将获取这些参数中的第一个。由于tol_low
和tol_high
是 not 持久的(不存储在数据库中),因此这意味着它将退回到class属性None
上。
这里的计算非常简单,因此我建议您将其转换为properties [Python-doc]:
class MeasurementParameter(models.Model):
tolerance = models.FloatField()
set_value = models.FloatField()
@property
def tol_low(self):
return self.set_value * (100-self.tolerance)/100
@property
def tol_high(self):
return self.set_value * (100+self.tolerance)/100
def tolerance_band(self):
return self.tol_high, self.tol_low
因此,在此我们将在必要时评估属性。这更可靠:如果更改对象的tolerance
或set_value
,则该对象的tol_low
和tol_high
将有所不同。因此,没有可用的复杂代码来更新相关更新的值。 calc_all_bands
也不是必需的,因为仅在需要时进行计算。
请注意,您不能在Django ORM过滤器等中使用属性。在这种情况下,您可以将该属性编码为查询表达式,并用这些注释注释queryset。