2015-08-06 9 views
5

Mam problemy z nowymAdnotacje na wielu stołach z Django 1.8 ORM

Powiedzmy mam następujące 3 modele:

class Author(models.Model): 
    name = models.TextField() 

class Book(models.Model): 
    author = models.ForeignKey(Author, related_name='books') 
    title = models.TextField() 
    is_fiction = models.BooleanField() 

class SpeakingEvent(models.Model): 
    author = models.ForeignKey(Author, related_name='events') 
    date = models.DateField() 

Chciałem dostać jeden queryset z Autorzy uwagami wraz z liczbą opublikowanych książek fikcyjnych i liczbą przyszłych wystąpień.

Tak, mogę wykonać następujące czynności:

Author.objects.all().annotate(
    future_speaking=Sum(Case(
     When(events__date__gte=timezone.now(), 
      then=1), 
     default=0)), 
    fiction_count=Sum(Case(
     When(books__is_fiction=True, 
      then=1), 
     default=0)), 
) 

Jednak uzyskane liczby są zbyt wysokie. Jeśli istnieje m książek i n zdarzeń, to kończymy <correct_result> * m dla liczby zdarzeń, <correct_result> * n dla liczby książek. Jest to spowodowane sposobem, w jaki django łączy dwie tabele razem z lewym złączeniem. Wyniki są poprawne, jeśli pominę jedną z adnotacji.

Czy jest jakiś sposób, aby zmienić połączenia są usunąć duplikaty z klauzulą ​​when?

+1

To wydaje się być to: https://docs.djangoproject.com/en/1.8/topics/db/aggregation/#combining-multiple-aggregations hodowli to głowa. Niestety moja sprawa nie ogranicza się tylko do Count(), ale dodam obejście, które wymyśliłem – JeffS

Odpowiedz

1

To co zrobiłem, to liczenie wraz z nim i dzielenie kodu.

Author.objects.all().annotate(
future_speaking_divide_count=Count('events'), 
future_speaking=Sum(Case(
    When(events__date__gte=timezone.now(), 
     then=1), 
    default=0)), 
fiction_count=Sum(Case(
    When(books__is_fiction=True, 
     then=1), 
    default=0)), 
fiction_count=Count('books') 
) 
Powiązane problemy