2017-07-18 91 views
1

我試圖使用註釋值來過濾使用F表達式的查詢集,但事實證明它並不像我期望的那樣行爲。Django聚合和註解行爲比較

我想過濾查詢集中的對象qs其屬性some_prop是該查詢集的最大值。例如:

set(qs.values_list('some_prop', flat=True)) 

將輸出:

set([1, 3, 5, 7, 9]) 

和我的目標由值9,即最大值過濾qs。我可以很容易地實現,使用聚合:

max_prop = qs.aggregate(max_prop=Max('some_prop'))['max_prop'] 
qs.filter(some_prop=max_prop) 

但我想凝結在一個查詢這個行爲,所以我用了一個註釋,而不是聚集:

qs.annotate(max_prop=Max('some_prop')).filter(some_prop=F('max_prop')) 

然而,這並不表明同樣的行爲。實際上這只是按照所有some_prop值進行篩選,而不是最大值。

我錯過了什麼?從註釋和聚合功能中必定會有一些誤解。

回答

0

由於您的註釋並未採用一對多關係中的值,因此相關對象集中的最大值將被註釋到與該集相關的對象,因此將採用Max(針對每個對象)只有一個值 - some_prop - 並附加到查詢集中的每個對象;這是不直接訪問上過濾-some_prop /不同:

當指定一個annotate()子句,在查詢集 每個對象將具有指定值註釋。

對於單個表格,您需要首先進行聚合以獲取最大值,然後過濾該值。

+0

所以我沒有辦法在'annotate'的單個查詢中實現行爲。 – dabadaba

+0

@dabadaba有一種解決方法,使用'.values'將所有對象分組爲一個並獲取最終的最大值:https://stackoverflow.com/questions/9838264/django-record-with-max-element –