2010-04-03 24 views
1

我在做這個查詢:Django的ORM:訂購W /聚合函數 - 無特殊處理

SomeObject.objects.annotate(something=Avg('something')).order_by(something).all() 

我通常在我的模型聚集現場,我有Django的信號用來保持同步,但是在這種情況下perfomance不是一個問題,所以我想我會保持簡單,只使用子查詢。

但是,這種方法提出了意想不到的問題。 這一切的偉大工程,如果聚合函數的結果是這樣的:

[5.0, 4.0, 6.0 … (etc, just numbers)] 

但是,如果你在某些None的混合比是有序的這樣的:

[None, 5.0, 4.0 …] 

的問題是,沒有具有更高的價值比任何數字,而它應該有值至多值0.

我使用PostgreSQL並沒有測試w /其他數據庫。我還沒有實際檢查產生何種查詢等

我的工作圍繞它通過只在內存中的排序:

sorted(…, key=lambda _:_.avg_rating if _.avg_rating is not None else 0) 

所以我只是好奇,如果有一種方法只用做Django ORM?或許.where?或者是其他東西?

回答

2

只需通過extra()添加has_something = 1,0,然後在has_something和something上同時排序,如何?

with_avg = SomeObject.objects.annotate(avg=Avg('something')) 
with_avg_and_has = with_avg.extra(select={'has_something': 'something is NULL'}) 
sorted_result = with_avg_and_has.order_by('-has_something', '-avg').all() 

從最嚴格的意義上講不是100%的ORM,但它將排序推回到DB中。