我有一些这样的类;
class RawMaterial(models.Model):
name = models.CharField(max_length=100)
class Product(models.Model):
name = models.CharField(max_length=100)
amount = models.IntegerField()
raw_materials = models.ManyToManyField(RawMaterial, through='MaterialProduct', related_name='products')
class MaterialProduct(models.Model):
raw_material = models.ForeignKey(RawMaterial, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
material_price = models.FloatField()
material_rate = models.FloatField()
我想写一个名称为calculate_total_price
的方法,我的方法将使用Product的amount
和MaterialProduct的material_price
,material_rate
。 要设计一个正确/美观/可维护的项目,我应该在哪里编写我的方法?models.py
还是views.py
?
提前谢谢。
按照胖模型瘦视图的方法,我建议您将该计算放在models.py
中。
它可能看起来像这样:
class MaterialProduct(models.Model):
# attributes
def calculate_total_price(self):
# perform calculation with
# self.product.amount
# self.material_price
# self.material_rate
return result
您也可以从模板 ({{ object.calculate_total_price }}
( 调用此方法以显示总价。
现在,如果您需要多次调用此方法,那么问题就出现了:如果结果没有更改,为什么还要再次运行该方法?
因此,我会更进一步,使其成为一个属性:
class MaterialProduct(models.Model):
# attributes
@property
def total_price(self):
# perform calculation
return result
或者,如前所述,如果您不希望总价格每隔几秒钟就发生变化,也许您想采用cached_property
:
from django.utils.functional import cached_property
class MaterialProduct(models.Model):
# attributes
@cached_property
def total_price(self):
# perform calculation
return result
总价现在可作为模板中的任何其他字段使用 ({{ object.total_price }}
(。如果使用cached_property
则计算将仅执行一次,并且将缓存结果。再次调用该属性将从缓存中检索结果,并且可以节省对数据库和 CPU 处理时间的命中。