5👍
This is expected behavior. When you evaluate
product.parameters.all()[0]
this means you make a database fetch. So Django will fetch the first of these parameters. Since the tol_low
and tol_high
are not persistent (not stored in the database), this means that it will fallback on the class attribute, which is None
.
The calculations here, are rather simple, so I propose that you convert these to 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
Here we thus will evaluate the property when necessary. This is more robust: if you change the tolerance
of an object, or the set_value
, then the tol_low
and tol_high
will be different for that object. So there is no complex code in place to update the value for relevant updates. The calc_all_bands
is not necessary either, since calculations are simply done when requested.
Note that you can not use properties in Django ORM filters, etc. In that case, you can encode the property as a query expression and annotate the queryset with these.