【问题标题】:Django / Python - Querying calculated fieldDjango / Python - 查询计算字段
【发布时间】:2020-05-17 15:22:17
【问题描述】:

我有以下模型,想对分配的外键进行计算,然后对金额求和。

class Fundraising(models.Model):
    @property
    def amount_raised(self):
        amount_raised = FundraisingDonation.objects.filter(
                            fundraising_event=self,
                            ).aggregate(donationamount=Coalesce(Sum('donationamount'), 0.00))['donationamount']
        return amount_raised

class FundraisingDonation(models.Model):
    donationamount = models.DecimalField(max_digits=11, decimal_places=2, default=0)


class Testmodel(models.Model):
      organisation = models.ForeignKey(Organisation, on_delete=models.CASCADE)
      allocation = models.ForeignKey(Fundraising, on_delete=models.CASCADE, related_name='items')
      percentshare = models.DecimalField(max_digits=11, decimal_places=2, default=0) #SET BY USER

     @property
     def amount(self):
         amount = self.allocation.amount_raised * self.percentshare
         return amount

上面的“金额”模型属性计算每个模型实例的金额字段。

我现在正在尝试在新模型上汇总每个组织的金额,但是以下不起作用,因为我不相信我可以在计算字段上运行查询?

class Totals(models.Model):
    totals = total + totalB + totalC
    @property
    def total(self):
        total = Testmodel.objects.filter(
                           organisation=self.organisation
                            ).aggregate(amount=Coalesce(Sum('amount'), 0.00))['amount']

有没有办法修改最后一行以使其正常工作,或者重新执行这一行的计算?我也试过聚合(Sum(amount_raised * percentshare)),但这似乎也不起作用?

【问题讨论】:

    标签: python django django-models sum aggregate


    【解决方案1】:

    您不能在 @property 上进行聚合,因为该属性在数据库端是未知的。

    你可以做的是.annotate(…) [Django-doc]Organisations 的查询集例如:

    from django.db.models import F, Sum
    
    Organisation.objects.annotate(
        total=Sum(
            F('testmodel__allocation__amount_raised') * F('testmodel__percentshare')
        )
    )

    由此查询集产生的每个Organisation 都会有一个名为.total 的额外属性,其中包含相关 testmodel 项的amount_raised 值的总和,乘以@987654330 @。

    编辑:由于amount_raised是一个属性,我们需要在FundraisingDonation模型上进行聚合,所以:

    from django.db.models import F, Sum, Value
    from django.db.models.functions import Coalesce
    
    Organisation.objects.annotate(
        total=Coalesce(Sum(
            F('testmodel__allocation__fundraising__donationamount') *
            F('testmodel__percentshare'), Value(0))
        )
    )

    【讨论】:

    • 谢谢。虽然不确定这种方法是否有效,因为 amount_raised 也是一个属性字段?我还需要能够将总属性与其他 2 个总属性相加以得到总和(即 Summedtotals = TotalA + TotalB + TotalC - 所以如果这只是一个注释属性,我将无法将结果添加到任何东西还有吗?
    • @Oliver:你能分享一下你FundraisingDonation模型的相关部分吗?
    • 用每个模型的相关部分更新了问题 - 我基本上需要对计算(fundraising.allocation.amount_raised)的计算(@property def total)进行计算(总计)!
    • @Oliver:FundraisingDonation 有一个ForeignKeyFundraising
    • 是的,没错。 FundraisingDonation 也有这个字段:fundraising_event = models.ForeignKey(Fundraising, on_delete=models.CASCADE)
    猜你喜欢
    • 2018-08-08
    • 2010-12-11
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 2022-06-21
    相关资源
    最近更新 更多