Django Sum关于不同的值

时间:2017-12-29 10:26:19

标签: django aggregate distinct

我有三种模式:

ModelA,ModelB和ModelC

ModelB有一个名为value的字段,我尝试聚合。但是为了找到正确的ModelB实例,我必须过滤Mo​​delC的字段,这意味着我将有重复。在ModelB实例上使用distinct子句意味着我不能使用Sum聚合,因为这将从Django引发NotImplementedError(Distinct + Aggregate未实现)。

查询:

ModelB.objects.filter(model_a=some_model_a, model_c__in=[some_vals]).distinct('id').aggregate(Sum('value'))

我可以这样做:

models_b = ModelB.objects.filter(model_a=some_model_a, model_c__in=[some_vals]).distinct('id')
sum = 0
for model_b in models_b:
   sum += model_b.value

这显然非常沉重和缓慢。无论如何都要绕过NotImplementedError的问题吗?

我已经尝试过SubQueries,带有DistinctSum的pg_utils(几乎我需要的东西,但我需要区分id而不是值)和一些带值的东西。

编辑:我忘了提到ModelC有一个到ModelB的ForeignKey,而ModelB有一个到ModelA的ForeignKey。因此1 ModelA有N个ModelBs,1个ModelB有N个ModelAs。

Edit2:我忘了提到我将整个事情映射为SQL查询并且它有效。但是,我需要DjangoORM的灵活性。否则我会在另一个地方头疼。在那里我使用group by子句而不是不同的值,但我不知道如何在DjangoORM中实现这一点。

1 个答案:

答案 0 :(得分:0)

我认为这应该有用,

models_b_id = ModelB.objects.filter(model_a=some_model_a, model_c__in=[some_vals]).distinct('id').values_list('id',flat=True)
stats = ModelB.objects.filter(id__in=model_b_id).aggregate(sum=Sum('values'))

查询比循环更快。