我有三个型号:
ModelA,ModelB和ModelC
ModelB有一个名为value的字段,我尝试聚合。但是为了找到正确的ModelB实例,我必须过滤ModelC的字段,这意味着我将有重复。在ModelB实例上使用distinct子句意味着我不能使用Sum聚合,因为这将从Django引发NotImplementedError(Distinct + Aggregate未NotImplemented)。
查询:
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中实现这一点。
我认为这应该有用,
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'))
查询比循环更快。