在Django模型的属性中使用聚合

Mat*_*kin 11 django django-models django-aggregation

架构描述

在此输入图像描述

项目可能有多个项目项目,项目项目可能有多个购置成本.例如,资本项目#1包含两个项目项:

  1. 数量.购买1台生产设备
    • 从供应商处购买设备需要花费5,000美元
  2. 数量.由工作人员构建的1个测试夹具
    • 购买12美元,购买总额为12,000美元.

生产设备可能只有一个与购买相关的成本.但是,测试夹具可能具有与构造它相关的多个成本.

欲望

我希望能够确定每个项目的总购置成本,并且我希望能够确定每个项目的总购置成本.基于以上示例:

  • 第1项总购置费= 5,000美元
  • 第2项总购置成本= 12,000美元
  • 资本项目总购置成本= 17,000美元

问题

  1. 如若total_acquisition_costs使用Django的聚集来计算或保存为一个DecimalFieldProjectProjectItem模式?
  2. 我应该total_acquisition_costsProjectItemProject模型创建一个属性吗?创造财产我的直觉是肯定的.

    我的直觉是使用聚合来计算值,以避免数据库非规范化.具体来说,我倾向于使用Django的聚合Sum函数来创建total_acquisition_costs属性.但是,我并不知道如何将聚合作为属性放在模型上,以便它只返回一个值而不是一个字典.

现行守则

注意:我当前的代码不使用Django的聚合功能,但它可以工作.

class ProjectItem(models.Model):
    project = models.ForeignKey(CapExProject)
    name = models.CharField(max_length=128)

    @property
    def total_acquisition_costs(self):
        acquisition_costs = self.acquisitioncost_set.only(
                'amount')
        total_acquisition_costs = 0
        for acquisition_cost in acquisition_costs:
        total_acquisition_costs += acquisition_cost.amount
        return total_acquisition_costs
Run Code Online (Sandbox Code Playgroud)

Bri*_*ket 14

我喜欢你使用Sum的想法,但把它作为一个属性.这样的事情应该有效:

class Project(models.Model):
    @property
    def total_acquisition_costs(self):
        return AcquisitionCost.objects.filter(item__project=self).aggregate(total=Sum("amount"))["total"]

class ProjectItem(models.Model):
    @property
    def total_acquisition_costs(self):
        return self.acquisitioncost_set.aggregate(total=Sum("amount"))["total"]
Run Code Online (Sandbox Code Playgroud)