2011-11-11 20 views
7

tengo 4 modelos y quiero recuperar una unión entre ellosDjango revertir relación con select_related

ModelA

class ModelA(models.Model): 
    product = models.ForeignKey(ModelB) 
    group = models.ForeignKey(Group) 

ModelB

class ModelB(models.Model): 
    title = models.CharField() 

ModelC

class ModelC(models.Model): 
    product = models.ForeignKey(ModelB) 
    group = models.ForeignKey(ModelD) 

ModelD

class ModelD(models.Model): 
    name = models.CharField() 

Ahora quiero que todos mis ModelA objetos se unieron con ModelB, ModelC y ModelD en SQL esto es algo muy fácil de hacer. Simplemente haga combinaciones entre tablas. Con Django ORM estoy atascado porque solo puedo hacer una relación directa.

que esté haciendo esto

ModelA.objects.all().select_related(product) 

pero no puedo unirse a ModelC ya he leído this article, pero yo no quiero bucle sobre mi lista grande, hacer una cosa simple! Y quiero golpear la base de datos solo una vez.

Estoy usando la última versión de Django y espero que ya haya una solución para esto, de la que no tengo conocimiento.

Gracias.

+0

Ha intentado algo como esto: 'ModelA.objects.all().select_related ('product', 'product__modelc', 'product__modelc__group') ' ? No publicar esto como respuesta porque no estoy absolutamente seguro de si sería lo que quieres. –

+1

@bildja: 'select_related' does * not * admite recorridos. –

Respuesta

8

Ver documentos en prefetch_related. Es solo un desarrollador en este momento, pero llegará con Django 1.4. Si puede esperar o puede ejecutar en el tronco. Podrás usar eso.

Mientras tanto, puedes probar django-batch-select. Básicamente sirve para el mismo propósito.

3

Editar: después de volver a leer el problema, la solución no es tan simple.

El docs dicen:

select_related se limita a las relaciones de valor único - un uno-a-clave y extranjera.

Django 1.4 querysets tendrá el método prefetch_related, que definitivamente deberías leer. Parece que no podrá hacerlo en una sola consulta, pero puede hacerlo en 2 o 3. Definitivamente debería echar un vistazo y actualizar a la versión de desarrollo si realmente la necesita.

Si no puede usar la versión dev y no puede esperar 1.4, django también admite custom SQL queries.

+0

Correcto. 'prefetch_related' no lo hace todo en una sola consulta como select_related. Simplemente, simplemente no hay forma de hacer eso. Está destinado a que el problema de consulta n + 1 donde el bucle a través de los elementos relacionados da como resultado una consulta para cada ciclo. En cambio, primero hace una consulta para la relación y luego guarda el resultado en caché para usarlo más adelante. –

Cuestiones relacionadas