2016-09-06 46 views
0

假设我有一个与模型B具有一对多关系的模型A,模型B与模型C具有一对一的关系。模型C具有包含数值的属性X.这是如下图所示:组中的Django查询差异

models illustration

什么是表达一个查询,我希望在那里它的相关模型的属性X C'S(通过B型)有一定比例模式A的所有实例的最佳方法他们之间的差异?

例如:

我希望所有A的其中任何相关C型的X属性具有20%以上的差:

MODELA [ID = 1]

模型烧烤[ A1:B1:C:attrX => 10,A1:B2:C:attrX => 14,A1:B3:C::A:B1,A1:B2,A1:B3]

模型Cs attr x值[A1: attrX => 13]

此示例将限定为bec澳洲英语A1:B1:C:attrX具有与至少一个其它attrX

EDIT 1 20%或更高的区别:

我也有兴趣在所有模型铯通过B或A分组,如果其他查询不可行。

甚至所有模型民宿按分组的...

回答

1

我希望所有A的其中任何相关的C型的X属性有20%以上

的差异如果任何CX为A的有%20的差异那么肯定MAX和MIN该A的Cx至少有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的A对象,然后我们过滤该值。根据您的字段类型,您可能还需要指定output_field

我不知道你的问题的具体情况,但我也建议你检查可用aggregation functions,也许标准偏差或方差会有所帮助。

参考:

0

这可能是在ORM可行的,但它听起来像的那种,这将是一个混乱的事情(需要内确保这些的计数所有人的平均数的20%与他们的呼叫数相同)。这对于预取来说似乎是一个很好的机会。也许类似

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

然后你可以在python中应用你的过滤,这将使它有点更受检查,应该只运行有限数量的查询。唯一的问题是,你的查询集希望不会太大,以至于不能完全针对此结果进行迭代。

如果此方法效果不佳,可以通过添加一列来指示是否符合您的低变化标准,并在保存BC的实例时进行更新。

+0

将有10M左右的项目,这将是经常更新。我认为一个有Postgres的ORM解决方案可以完成繁重的工作。 –