Django ma świetną nową funkcję adnotate() dla zapytań. Nie mogę jednak zmusić go do poprawnego działania wielu adnotacji w jednym zapytaniu.Django adnotate() wiele razy powoduje błędne odpowiedzi
Na przykład
tour_list = Tour.objects.all().annotate(Count('tourcomment')).annotate(Count('history'))
Trasa może zawierać wiele tourcomment i historia wpisy. Próbuję uzyskać liczbę komentarzy i wpisów historii dla tej trasy. Uzyskane wartości będą niepoprawne. Wartości te będą niepoprawne. Jeśli istnieje tylko jedno wywołanie adnotacji(), wartość będzie poprawna.
Wydaje się, że istnieje pewien efekt multiplikatywny pochodzący z dwóch s. LEFT OUTER JOIN
. Na przykład, jeśli trasa ma 3 historie i 3 komentarze, 9 będzie wartością dla obu. 12 historii + 1 komentarz = 12 dla obu wartości. 1 historia + 0 komentarzy = 1 historia, 0 komentarzy (to się dzieje, aby zwrócić prawidłowe wartości).
Powstały połączenia SQL jest:
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
Próbowałem połączenie wyników z dwóch querysets które zawierają jeden wezwanie do opisywania(), ale to nie działa dobrze ... Nie można naprawdę gwarantuję, że zamówienie będzie takie samo. i wydaje się zbyt skomplikowany i niechlujny, więc szukałem czegoś lepszego ...
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
Dzięki za pomoc. Stackoverflow uratował mój tyłek w przeszłości z wieloma już odpowiedział na pytania, ale nie byłem w stanie znaleźć odpowiedzi na to jeszcze.
... który wciąż jest straszne rozwiązanie, jak to tylko odfiltrowuje wszystkie duplikaty z ogromnej wyniku – dragonroot
To również działa tylko z Liczyć. Mam podobny problem z liczbą i sumą, a podczas gdy ustawienie różni się od prawdziwej, powoduje, że liczba jest dokładna, suma jest wciąż mnożona. – StephenTG
Ponadto, dla opisu błędu "Sum" patrz: https: //code.djangoproject .com/ticket/10060 – sobolevn