首页 > 解决方案 > 如何计算 django 模型字段

问题描述

我的模型中有以下字段:

class Materiale(models.Model):
    quantity=models.DecimalField(max_digits=5, decimal_places=2, default=0)
    price=models.DecimalField( max_digits=5, decimal_places=2, default=0)
    VAT=models.DecimalField(max_digits=5, decimal_places=2, default=0)
    VAT_amount=models.DecimalField(max_digits=5, decimal_places=2, default=0)

但 VAT_amount 是quantity*price*VAT.

如何在我的数据库中自动存储该值???字段 (VAT_amount) 存在于数据库中很重要。

谢谢。

标签: jquerydjangodjango-modelsdjango-rest-frameworkdjango-views

解决方案


不要将其存储在您的数据库中。如果它完全依赖于其他字段,通常最好计算列。实际上,假设您更新了其中一个字段,那么您也需要更新该字段VAT_amount。但是如果你做了很多视图、查询等,那么最终你很可能会犯错误而忘记更新。

您可以删除该VAT_amount字段,然后.annotate(..)您的查询集以包含VAT_amount,例如:

from django.db.models import F

Materiale.objects.annotate(VAT_amount=F('quantity')*F('price')*F('vat'))

从此查询集产生的Materiale对象将有一个额外的属性,然后包含公式的结果。.VAT_amount

如果你经常需要这个,你可以将它添加到这个模型的管理器中,这样每次你访问时它都会自动完成Materiale.objects

class MetarialeManager(models.Manager):

    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).annotate(
            VAT_amount=F('quantity')*F('price')*F('vat')
        )

class Materiale(models.Model):
    quantity=models.DecimalField(max_digits=5, decimal_places=2, default=0)
    price=models.DecimalField( max_digits=5, decimal_places=2, default=0)
    VAT=models.DecimalField(max_digits=5, decimal_places=2, default=0)

    objects = MaterialeManager()

推荐阅读