[Django]-Setting local variables in a django model

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.

Leave a comment