2012-08-27 4 views
7

Considerate questa query:In django, c'è un modo per annotare direttamente una query con un oggetto correlato in una singola query?

query = Novel.objects.< ...some filtering... >.annotate(
    latest_chapter_id=Max("volume__chapter__id") 
) 

In realtà quello che mi serve è quello di annotare ogni Novel con la sua ultima Chapter oggetto, così dopo questa query devo eseguire un'altra query per selezionare oggetti reali per gli ID annotati. IMO questo è brutto. C'è un modo per combinarli in una singola query?

+0

Potresti annotare i capitoli con i romanzi? –

+0

Non mi sembra possibile, perché ho bisogno solo dell'ultimo capitolo per ogni romanzo, ma un romanzo ha molti capitoli e i capitoli sono in volumi diversi. Per quanto ne so, 'distinto()' non è utile in questo caso (correggimi se sbaglio), e non conosco altro modo per selezionare esattamente un capitolo tranne che per iniziare da un romanzo. Qualche idea? – SAPikachu

risposta

2

No, non è possibile combinarli in una singola query.

È possibile leggere il seguente numero blog post per trovare due soluzioni alternative.

+2

La risposta di runa-kaagaard è migliore ora. – qznc

+1

Il post collegato suggerisce l'uso di extra() nella query. A partire da Django 1.8, extra() non è raccomandato ed è deprecato. – johanno

15

Sì, è possibile.

Per ottenere un set di query che contiene tutti i capitoli che sono l'ultimo di loro romanzi, semplicemente:

from django.db.models.expressions import F 
from django.db.models.aggregates import Max 

Chapters.objects.annotate(last_chapter_pk=Max('novel__chapter__pk') 
      ).filter(pk=F('last_chapter_pk')) 

provata su Django 1.7.