Foros del Web » Programando para Internet » Python »

Django: filtrar un queryset con otros querysets

Estas en el tema de Django: filtrar un queryset con otros querysets en el foro de Python en Foros del Web. Hola a todos, estoy desarrollando un sitio con Django y tengo un problema o mejor dicho una duda. Tengo estos 4 modelos: @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); Código ...
  #1 (permalink)  
Antiguo 04/05/2012, 08:09
 
Fecha de Ingreso: mayo-2012
Mensajes: 1
Antigüedad: 12 años, 7 meses
Puntos: 0
Pregunta Django: filtrar un queryset con otros querysets

Hola a todos, estoy desarrollando un sitio con Django y tengo un problema o mejor dicho una duda. Tengo estos 4 modelos:

Código Python:
Ver original
  1. class Involucrados (models.Model):
  2.     nombre = models.CharField(max_length=15)
  3.     apellido = models.CharField(max_length=15)
  4.     doc_num = models.CharField(max_length=11)
  5.     id_localidad = models.ForeignKey(Localidades)
  6.  
  7. class Expedientes (models.Model):
  8.     fecha_presentacion = models.DateField()
  9.     fecha_ultimo_mov = models.DateField()
  10.     id_localidad = models.ForeignKey(Localidades)
  11.     forma_presentacion = models.CharField(max_length=15, choices=FP)
  12.     involucrados = models.ManyToManyField(Involucrados, through='Expe_Invo')
  13.  
  14. class Expe_Invo (models.Model):
  15.     id_expediente = models.ForeignKey(Expedientes)
  16.     id_involucrado = models.ForeignKey(Involucrados)
  17.     categoria = models.CharField(max_length=2, choices=CAT)
  18.     repre_entidad = models.CharField(max_length=2, choices=SINO)
  19.     nombre_entidad = models.CharField(max_length=50)
  20.     cargo_entidad = models.CharField(max_length=30)
  21.  
  22. class Relatos_Observaciones (models.Model):
  23.     id_expediente = models.ForeignKey(Expedientes)
  24.     texto = models.CharField(max_length=80)
  25.     categoria = models.CharField(max_length=2, choices=CAT)

Y ahora mi duda es la siguiente. Dado un doc_num de Involucrados y un texto de Relatos_Observaciones yo tengo 2 querysets:
q1 = Expe_Invo.objects.filter(id_involucrado.doc_num=x)
q2 = Relatos_Observaciones.objects.filter(texto=y)

Ahora esos 2 querysets tienen una lista de id_expediente's. Como puedo hacer un tercer queryset filtrando la tabla de Expedientes por una lista convinada (para no repetir id_expediente) de q1 y q2. Espero haberme explicado bien y desde ya muchas gracias

Última edición por AlvaroG; 04/05/2012 a las 10:02 Razón: coloreado de código
  #2 (permalink)  
Antiguo 04/05/2012, 21:04
 
Fecha de Ingreso: octubre-2010
Mensajes: 83
Antigüedad: 14 años, 1 mes
Puntos: 4
Respuesta: Django: filtrar un queryset con otros querysets

Voy a poner lo primero que se me viene a la cabeza (no fusilarme plz)

Forma 1
Código:
q1 = Expe_Invo.objects.filter(id_involucrado.doc_num=x).values('id_expediente')
q2 = Relatos_Observaciones.objects.filter(texto=y).values('id_expediente')

expediente_ids = set(
    [i['id_expediente'] for i in q1] +
    [i['id_expediente'] for i in q2]
)

q3 = Expedientes.objects.filter(pk__in=expediente_ids)
La forma 2 ya me dio flojera pero basicamente seria todo en una sola consulta obviamente con raw SQL.

BTW no uses "_" para nombres de clases.
  #3 (permalink)  
Antiguo 07/05/2012, 07:36
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Django: filtrar un queryset con otros querysets

snahor_,
La forma que proponés funciona, pero obligaría a obtener todos los registros de ambos querysets, cuando definitivamente eso es trabajo del ORM. Estuve viendo muy por encima el ORM de Django, y no encontré la forma correcta de expresar esta relación (que no quiere decir que no exista, solamente viché por un par de minutos las opciones disponibles).

Basicamente lo que se quiere es algo como

Código SQL:
Ver original
  1. SELECT E.*
  2. FROM Expedientes E
  3.     INNER JOIN Expe_Invo EI ON (E.id_expediente = EI.id_expediente)
  4.     INNER JOIN Relatos_Observaciones RO ON (E.id_expediente = RO.id_expediente)
  5. WHERE
  6.     RO.texto = y
  7.     OR EI.doc_num = x;

Partiendo de una consulta correcta siempre es más fácil hacer la "traducción" al ORM


Saludos.
  #4 (permalink)  
Antiguo 07/05/2012, 11:17
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Django: filtrar un queryset con otros querysets

No estoy del todo seguro que esto funcione por que no pude probarlo en los modelos que das de ejemplo. La consulta de AlvaroG mas o menos sería de la siguiente manera.

Código Python:
Ver original
  1. from django.db.models import Q
  2. ...
  3. Expediantes.objects.filter(Q(Expe_Invo__doc_num=x) | Q(Relatos_Observaciones__texto=y))

Etiquetas: django
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:54.