Django查询组中的差异

时间:2016-09-06 19:57:14

标签: django django-models

假设我有一个与模型B具有一对多关系的模型A,它与模型C具有一对一的关系。模型C具有包含数值的属性X.这说明如下:

models illustration

表达查询的最佳方式是什么?我想要模型A的所有实例,其相关模型C上的属性X(通过模型B)在它们之间有一定的百分比差异?

例如:

我想要所有相关模型C的X属性相差20%或更多的所有A:

MODELA [ID = 1]

型号Bs [A1:B1,A1:B2,A1:B3]

模型Cs attr x值[A1:B1:C:attrX => 10,A1:B2:C:attrX => 14,A1:B3:C:attrX => 13]

此示例符合条件,因为A1:B1:C:attrX与至少一个其他attrX的差异为20%或更高

编辑1:

如果其他查询不可行,我也会对按B或A分组的所有模型C感兴趣。

甚至所有模型B都按A ...

分组

2 个答案:

答案 0 :(得分:1)

  

我想要所有相关模型C的X属性有20%或更多差异的所有A

如果A的C.x中的任何一个具有%20的差异,那么该A的MAX和MIN C.x肯定具有至少%20或更大的差异。您可以根据该事实构建查询。使用aggregate expressions,您可以执行以下操作:

A.objects.annotate(
      max_diff=(Max('b__c__x') - Min('b__c__x')) * 100 / Min('b__c__x')
    ).filter(max_diff__gte=20)

当然b,c代表外国或多对多关系的相关名称。这将首先注释具有max_diff百分比的对象,然后我们过滤该值。根据您的字段类型,您可能还需要指定output_field

我不知道您问题的具体细节,但我也建议您查看可用的aggregation functions,也许标准偏差或差异会有所帮助。

参考:

答案 1 :(得分:0)

这在orm中可能是可行的,但这听起来像是一堆乱七八糟的东西(需要确保那些在所有平均值的20%范围内的数量与数量相同)打电话给他们)。这似乎是一个预取的好机会。也许像是

for a in A.objects.prefetch_related("b_set__c"):
    cs = [b.c for b in a.b_set.all()]

然后你可以在python中应用你的过滤,这将使它更可检查,并且应该只运行有限数量的查询。唯一的问题是,您的查询集可能不会太大而无法完全迭代此结果。

如果此方法效果不佳,可以通过添加列来指示这是否符合您的低变异性标准,并在保存B和{{1 }}