2016-09-06 53 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解決方案可以完成繁重的工作。 –