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.
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