Publicado el Dejar un comentario

Cómo hacer inners joins (concatenaciones internas) con la ORM de Django

Bueno, estamos ahora aquí en un proyecto que utiliza Django como su marco de trabajo.  Y aprendiendo su ORM (mapeo objeto-relacional) me tope con la necesidad de hacer las famosas concatenaciones (joins) entre dos o más entidades.

Anteriormente he trabajado con las ORM de java (Hibernate, EclipseLink) y de .Net (Entity Framework) así que la de ORM  de Django y su QuerySet debería ser capaz de hacer concatenaciones (joins).

Para hacer concatenaciones internas en Django, utilizamos la función select_related(). Según la documentación, esta función sólo sigue relaciones de llaves foráneas (foreign-key), es decir, de tablas hijas a tablas padre o relaciones de uno a uno.

Imagina los registros en una tabla que representa los artículos vendidos de una factura. Llamaremos a la table linea_factura. Esta tabla tendrá como llaves foráneas el identificador de la factura de la tabla factura y el identificador del artículo de la tabla articulo.

Con select_related() sólo podríamos seguir las relaciones de llaves foráneas, es decir sólo podríamos relacional las lineas de la factura con la factura y/o con los artículos pero no en el sentido contrario, es decir, de la factura hacia las lineas de la factura, o de artículos  la linea de artículo. Para esto existe otra función que aún no he probado y espero tratar más adelante.

El código siguiente, que omite la definición de los modelos,  para obtener el QuerySet quedaría así:

lineas_factura = linea_factura.objects.select_related(‘factura’)
.select_relate(‘articulo’).filter(factura__no = 89)

Una vez que el programa haga referencia a la variable lineas_factura, este QuerySet lanzará la consulta sql con dos joins y cargará con los registros de linea_factura y la información relacionada de la tabla factura y de la tabla artículo, donde el número de  factura sea igual a 89. Es decir, la factura número 89 y su detalle.

Espero les sea claro. Si no, comenta el post.

¡Hasta la próxima!