2012-02-07 16 views
33

He intentado prefetch_related() en django 1.4 desde el enlace troncal y no puedo realizar una búsqueda previa de búsqueda inversa.Django: ¿prefetch_related() sigue la búsqueda de relaciones inversas?

Mis modelos simplificados (cada libro tiene muchos precios):

class Book(models.Model): 
    # some fields 

class Price(models.Model): 
    book = models.ForeignKey(Book) 

de mi vista de consulta:

books = Book.objects.prefetch_related('price') 

Entonces, me dieron el mensaje de AttributeError:

AttributeError: Cannot find 'price' on Book object, 'price' is an invalid parameter to prefetch_related() 

Cómo ¿hazlo funcionar? Gracias.

+14

libros = Book.objects.prefetch_related ('price_set') – Acute

+2

@Jonathanz: Usted debe poner su comentario como la respuesta aceptada es decir, 'prefetch_related ('price_set')' – Medorator

Respuesta

61

Definir un nombre relacionado:

class Price(models.Model): 
    book = models.ForeignKey(Book, related_name='prices') 

y luego usarlo:

books = Book.objects.prefetch_related('prices') 
+31

Su respuesta me recuerda a la FOO_set por lo que la corrección puede también ser .prefetch_related ('price_set'). Por cierto, muchas gracias – Tianissimo

+1

No puedo reproducir esto en el caparazón. Aún hace consultas separadas, esperaba uniones. – pdvyas

+0

¡Hola! También he intentado esto, pero como @pdvyas dijo, hay consultas separadas. Esto no hace un join ... – Anton

0

Cuando usted no tiene definido un related_name de la relación, la relación inversa tiene _set anexa. Este es el caso cuando se accede a la relación inversa a partir de un objeto (por ejemplo some_book.price_set.all()), pero esto también funciona en prefetch_related:

books = Book.objects.prefetch_related('price_set') 

Tenga en cuenta que esto parece diferente de filtro, que qué acepte el nombre del otro modelo sin _set (por ejemplo, Books.objects.filter(price__currency='EUR')).

Lo anterior se probó con 1.11.8 (no en este código específico, pero sí, código similar).

Como alternativa, puede agregar un related_name, como lo muestra Jan Pöschko arriba.

Cuestiones relacionadas