在 Django 模型中设置局部变量

use*_*235 3 django django-models

我有以下模型:

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
Run Code Online (Sandbox Code Playgroud)

我希望使用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
Run Code Online (Sandbox Code Playgroud)

因此,在我看来,我尝试通过以下方式计算所有公差带:

product.calc_all_tol_bands()
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试获取局部变量:

product.parameters.all()[0].tol_low
Run Code Online (Sandbox Code Playgroud)

我一直都没有。

我需要做什么才能在 MeasurementParameter 模型中设置计算值?

约翰。

Wil*_*sem 5

这是预期的行为。当你评估

product.parameters.all()[0]
Run Code Online (Sandbox Code Playgroud)

这意味着您进行数据库提取。因此 Django 将获取这些参数中的第一个。由于tol_lowtol_high持久的(没有存储在数据库中),这意味着它将回退的类属性,它是None

这里的计算相当简单,因此我建议您将这些转换为属性[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
Run Code Online (Sandbox Code Playgroud)

因此,我们将在必要时评估该属性。这更健壮:如果您更改tolerance对象的 或set_value,则该对象的tol_lowtol_high将不同。所以没有复杂的代码来更新相关更新的值。该calc_all_bands要么是没有必要的,因为在请求时计算简单地完成。

请注意,您不能在 Django ORM 过滤器等中使用属性。在这种情况下,您可以将属性编码为查询表达式并使用这些注释查询集。