2010-10-15 11 views
5

Me gustaría filtrar un queryset por si una determinada subconsulta devuelve algún resultado. En SQL esto podría verse así:¿Cómo se "filtra" por "existe" en Django?

SELECT * FROM events e WHERE EXISTS 
    (SELECT * FROM tags t WHERE t.event_id = e.id AND t.text IN ("abc", "def")) 

En otras palabras, recupera todos los eventos que están etiquetados con una de las etiquetas especificadas.

¿Cómo puedo expresar esto usando la API QuerySet de Django en los modelos Event y Tag?

Respuesta

12

se puede hacer algo como esto:

q = Event.objects.filter(tag__text__in = ['abc', 'def']) 

Suponiendo que hay una ForeignKey de Tag a Event.

Explicación: Está filtrando Event objetos en función de un criterio específico. Con la sintaxis de subrayado doble, está accediendo al atributo text de las instancias Tag y luego adjuntando la condición IN. No tiene que preocuparse por unirse en la clave externa; Django lo hace por ti detrás de escena. En caso de que la curiosidad de ver la consulta generada, puede imprimirlo:

print q.query 
+0

Gracias Manoj, que parecen olvidar a menudo para tratar la "obvia" en Django y empezar a pensar en algo que es bastante complicado. –

5

solución de Manoj puede causar un problema cuando hay múltiples etiquetas para un evento.

La combinación interna de SQL devuelve todas las filas para que los eventos puedan tener resultados duplicados, la solución es agregar el método distinto.

q = Event.objects.filter(tag__text__in = ['abc', 'def']).distinct()

Cuestiones relacionadas