2009-08-12 12 views
21

Django, querysets için yeni ve büyük annotate() işlevine sahiptir. Ancak, tek bir sorguda birden fazla ek açıklama için düzgün şekilde çalışmasını sağlayamıyorum. ÖrneğinBirden çok kez Django annotate() yanlış yanıtlara neden olur

,

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

Bir tur birden tourcomment ve tarih giriş içerebilir. Bu tur için kaç yorum ve tarih girişi olduğunu anlamaya çalışıyorum. Ortaya çıkan

değerleri yanlış olacaktır. Sadece bir tane açıklama notu() varsa, değer doğru olur.

İki LEFT OUTER JOIN s'den gelen bir çeşit çoğullayıcı etki var gibi görünüyor. Örneğin, bir turun 3 geçmişi ve 3 yorumu varsa, 9 her ikisi için de sayı değeri olacaktır. Her iki değer için 12 hikaye + 1 yorum = 12. 1 geçmiş + 0 yorum = 1 tarih, 0 yorum (bu doğru değerleri döndürmek için olur).

sonuçlanan SQL çağrısıdır: I) (açıklama tek bir çağrı içeren iki Sorgu kümelerini sonuçları birleştirerek denedi, ama doğru çalışmıyor

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 

... Sen edemez gerçekten siparişin aynı olacağını garanti eder. ve çok karmaşık ve dağınık görünüyor, bu yüzden daha iyi bir şey arıyordum ...

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 

Yardımlarınız için teşekkürler. Stackoverflow geçmişte benim çoktan cevaplanmış sorularım ile popomu kurtardı, ama buna bir cevap bulamadım.

cevap

0

Bunun sorunununuzu çözeceğini garanti edemiyorum, ancak aramanıza .order_by() eklemeye çalışın. Yani: Bunun

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

nedeni django aksi özdeş sonuçlar seçilecek neden fıkra, ORDER BY tüm alanları seçmek gerektiğidir. .order_by() ekleyerek, ORDER BY yan tümcesini kaldırarak, bunun olmasını engellersiniz. Bu sorun hakkında daha fazla bilgi için bkz. the aggregation documentation.

40

Yorumunuz için teşekkürler. Bu oldukça işe yaramadı ama beni doğru yönde yönlendirdi. Sonunda) (her iki Sayısına ayrı ekleyerek bunu çözmek başardı çağırır:

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

... hala korkunç bir çözüm olan bu yalnızca Bu aynı zamanda sadece çalışır dev sonucu – dragonroot

+1

tüm çiftleri filtreler olarak sayın. Sayım ve bir Toplam ile benzer bir sorun yaşıyorum ve doğru olarak belirlenirken Sayımı doğru tutarken, Toplam hala – StephenTG

+0

ile çarpılır. Ayrıca, bir 'Sum' hata açıklaması için bkz: https: //code.djangoproject .com/ticket/10060 – sobolevn

İlgili konular