2012-08-27 14 views
7

considerar esta consulta:En django, ¿hay alguna manera de anotar directamente una consulta con un objeto relacionado en una sola consulta?

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

En realidad lo que necesito es para anotar cada Novel con su última Chapter objeto, así que después de esta consulta que tengo que ejecutar otra consulta para seleccionar objetos reales anotados por IDS. OMI esto es feo. ¿Hay alguna manera de combinarlos en una sola consulta?

+0

¿Podría anotar capítulos con novelas en su lugar? –

+0

No me parece posible, porque solo necesito el último capítulo para cada novela, pero una novela tiene muchos capítulos y los capítulos están en diferentes volúmenes. Por lo que sé, 'distinct()' es inútil en este caso (corrígeme si estoy equivocado), y no conozco otra forma de seleccionar exactamente un capítulo, excepto para comenzar desde la novela. ¿Algunas ideas? – SAPikachu

Respuesta

2

No, no es posible combinarlos en una sola consulta.

Puede leer el siguiente blog post para encontrar dos soluciones.

+2

La respuesta de rune-kaagaard es mejor ahora. – qznc

+1

La publicación vinculada sugiere el uso de extra() en la consulta. A partir de Django 1.8, extra() no se recomienda y está en desuso. – johanno

15

Sí, es posible.

Para obtener un conjunto de consultas que contiene todos los capítulos que son los últimos en sus novelas, sólo tiene que hacer:

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')) 

probado en Django 1.7.

Cuestiones relacionadas