2009-08-12 55 views
21

Django對查詢集有很好的新annotate()函數。但是,我無法讓它在單個查詢集中的多個批註中正常工作。Django批註()多次導致錯誤的答案

例如,

tour_list = Tour.objects.all().annotate(Count('tourcomment')).annotate(Count('history')) 

漫遊可以包含多個tourcomment和歷史條目。我試圖瞭解這次巡演有多少評論和歷史記錄。由此產生的

history__count and tourcomment__count 

值將不正確。如果只有一個annotate()調用,則該值將是正確的。

似乎有來自兩個LEFT OUTER JOIN s某種乘法效應。例如,如果一次旅程有3個歷史記錄和3個評論,則9將是兩者的計數值。對於兩個值,12個歷史+ 1個評論= 12。 1歷史記錄+ 0評論= 1歷史記錄,0條評論(這一次恰好會返回正確的值)。

產生的SQL調用是:

SELECT `testapp_tour`.`id`, `testapp_tour`.`operator_id`, `testapp_tour`.`name`, `testapp_tour`.`region_id`, `testapp_tour`.`description`, `testapp_tour`.`net_price`, `testapp_tour`.`sales_price`, `testapp_tour`.`enabled`, `testapp_tour`.`num_views`, `testapp_tour`.`create_date`, `testapp_tour`.`modify_date`, `testapp_tour`.`image1`, `testapp_tour`.`image2`, `testapp_tour`.`image3`, `testapp_tour`.`image4`, `testapp_tour`.`notes`, `testapp_tour`.`pickup_time`, `testapp_tour`.`dropoff_time`, COUNT(`testapp_tourcomment`.`id`) AS `tourcomment__count`, COUNT(`testapp_history`.`id`) AS `history__count` 
FROM `testapp_tour` LEFT OUTER JOIN `testapp_tourcomment` ON (`testapp_tour`.`id` = `testapp_tourcomment`.`tour_id`) LEFT OUTER JOIN `testapp_history` ON (`testapp_tour`.`id` = `testapp_history`.`tour_id`) 
GROUP BY `testapp_tour`.`id` 
ORDER BY `testapp_tour`.`name` ASC 

我試圖從組合中包含一個調用註釋()兩個查詢集的結果,但它不工作的權利...你不能真的保證訂單是一樣的。它似乎過於複雜和凌亂,所以我一直在尋找更好的東西...

tour_list = Tour.objects.all().filter(operator__user__exact = request.user).filter(enabled__exact = True).annotate(Count('tourcomment')) 
tour_list_historycount = Tour.objects.all().filter(enabled__exact = True).annotate(Count('history')) 
for i,o in enumerate(tour_list): 
    o.history__count = tour_list_historycount[i].history__count 

感謝您的任何幫助。 Stackoverflow保存了我過去很多已經回答過的問題,但是我還沒有找到答案。

回答

0

我不能保證這會解決您的問題,但可以嘗試追加.order_by()您的電話。那就是:

tour_list = Tour.objects.all().annotate(Count('tourcomment')).annotate(Count('history')).order_by() 

這樣做的原因是,django的需要選擇在ORDER所有字段BY子句,這導致選擇其它方面相同的效果。通過附加.order_by(),您將完全刪除ORDER BY子句,從而防止發生這種情況。有關此問題的更多信息,請參閱the aggregation documentation

40

感謝您的評論。這並不奏效,但它讓我朝着正確的方向前進。我終於可以通過添加不同的這兩個計數()來解決這個呼籲:

Count('tourcomment', distinct=True) 
+1

...這仍然是一個可怕的解決方案,因爲這僅僅是過濾掉了巨大成績 – dragonroot 2014-01-07 23:06:59

+1

這也只適用所有重複計數。我遇到了一個與Count和Sum類似的問題,並且將distinct設置爲true時,計數保持準確,Sum仍然相乘 – StephenTG 2014-03-18 20:32:08

+0

另外,對於Sum的錯誤描述,請參閱:https://code.djangoproject .com/ticket/10060 – sobolevn 2015-09-21 09:08:26