Django 为查询集提供了很棒的新 annotate() 函数。但是,对于单个查询集中的多个注释,我无法使其正常工作。
例如,
tour_list = Tour.objects.all().annotate( Count('tourcomment') ).annotate( Count('history') )
一个游览可以包含多个游览评论和历史条目。我正在尝试了解这次巡演有多少评论和历史条目。所结果的
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
我尝试将两个查询集的结果组合在一起,这些查询集包含一个对 annotate () 的调用,但它不能正常工作......你不能真正保证顺序是相同的。它似乎过于复杂和凌乱,所以我一直在寻找更好的东西......
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 过去用很多已经回答的问题拯救了我的屁股,但我还没有找到这个问题的答案。