2008-10-31 13 views
8

¿Cómo puedo crear una consulta para una unión externa completa a través de una relaciónch M2M utilizando la API django QuerySet?Unión externa completa en django

Si no es compatible, le daré una sugerencia sobre cómo crear mi propio administrador para hacerlo.

Editado para agregar: @ S. Lott: Gracias por la aclaración. La necesidad de OUTER JOIN proviene de la aplicación. Tiene que generar un informe que muestre los datos ingresados, incluso si aún está incompleto. No estaba al tanto del hecho de que el resultado sería una nueva clase/modelo. Tus sugerencias me ayudarán bastante.

Respuesta

11

Django no admite "uniones" en el sentido SQL habitual: admite la navegación de objetos.

Tenga en cuenta que una unión relacional (interna o externa) crea una nueva "clase" de entidades. Uno que no tiene una definición en Django. Por lo tanto, no existe un "conjunto de resultados" adecuado, ya que no hay una definición de clase para las cosas que recibes. Lo mejor que puede hacer es definir una tupla que se empaquetará con None para las combinaciones faltantes.

Una combinación externa izquierda (o derecha) tiene este aspecto. Crea dos subconjuntos disjuntos, aquellos que tienen un conjunto asociado de entidades relacionadas y aquellos que no lo tienen.

for obj in Model1.objects.all(): 
    if obj.model2_set().count() == 0: 
     # process (obj, None) -- no Model2 association 
    else: 
     for obj2 in obj.model2_set.all(): 
      # process (obj, obj2) -- the "inner join" result 

Una unión externa "completa" es una unión de los elementos restantes que no tienen relaciones.

for obj2 in Model2.objects.all(): 
    if obj2.model1_set().count() == 0: 
     # process (None, obj2) -- no Model1 association 

La cuestión es siempre, lo procesamiento haces con esta extraña colección de tres diferentes subconjuntos de los objetos?

El objetivo de una base de datos de objetos es enfocar el procesamiento en el objeto y sus objetos asociados.

La peculiar colección llamada "unión relacional" nunca está en el modelo de objeto original. Es una nueva clase de objetos construidos a partir de dos (o más) objetos originales.

Peor aún, las uniones externas crean una colección con varias subclases (unión interna, unión externa izquierda y unión externa derecha). ¿Qué significa esa colección de cosas ?

Espere, puede empeorar. Si el procesamiento incluye comprobaciones para los atributos faltantes (es decir, if someObj.anObj2attribute is None: estamos buscando esencialmente elementos Model1 sin Model2 objeto asociado. Ummm ... ¿por qué pusimos esos en la combinación externa, solo para filtrarlos usando una declaración if? ¿por qué no simplemente hacer consultas separadas proceso de amd cada subconjunto adecuadamente


Editar:?.. Cuando se está mostrando el estado de "incompleta", que no es una combinación externa en absoluto es mucho más simple es necesario crear una (o dos) colecciones separadas en su función de visualización para que se muestre su plantilla.

Primero, debe usar los códigos de estado, no la presencia o abso nce de una clave foránea. Las claves externas opcionales no tienen "razones": están allí o no. Un código de estado puede proporcionar matices de significado útiles ("incompleto", "por error", "roto", "no aplicable", "por eliminar", etc.)

errorList1 = Model1.objects.filter(status="Incomplete") 
errorList2 = Model2.objects.filter(status="Incomplete") 

Estas dos son las dos partes sin unión de una unión externa completa. A continuación, puede mostrar estas dos listas de errores en su plantilla con títulos de columna y códigos de estado adecuados y todo.

Usted puede incluso poner en una sola tabla para imitar el antiguo externa completa de personas informe usado para ver

<table> 
    <tr><th>Model1</th><th>Model2</th></tr> 
    {% for e1 in errorList1 %} 
    <tr><td>e1</td><td>NULL</td></tr> 
    {% endfor %} 
    {% for e2 in errorList2 %} 
    <tr><td>NULL</td><td>e2</td></tr> 
    {% endfor %} 
</table> 

Parece que una combinación externa completa informe. Sin la combinación externa completa.

+0

Tienes razón. Escribiré una vista que calcule la tabla necesaria para mi "FULL OUTER JOIN" en python y luego entregaré el resultado a la plantilla para su representación. Gracias. – Ber

Cuestiones relacionadas