2010-10-15 8 views
5

Vorrei filtrare un set di query se una determinata sottoquery restituisce risultati. In SQL, questo potrebbe essere il seguente:Come "filtrare" con "esiste" in Django?

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

In altre parole, recuperare tutti gli eventi contrassegnati con uno dei tag specificati.

Come posso esprimere questo utilizzando l'API QuerySet di Django sui modelli Event e Tag?

risposta

12

si può fare qualcosa di simile:

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

Supponendo che v'è una ForeignKey da Tag a Event.

Spiegazione: Si stanno filtrando gli oggetti Event in base a un criterio specifico. Utilizzando la sintassi del doppio trattino basso si accede all'attributo text delle istanze Tag e quindi alle condizioni IN. Non devi preoccuparti del join sulla chiave esterna; Django lo fa per te dietro le quinte. Nel caso in cui siete curiosi di vedere generato la query, è possibile stamparlo:

print q.query 
+0

Grazie Manoj, mi sembra di dimenticare spesso di provare il "ovvio" in Django e cominciare a pensare a qualcosa che è piuttosto complicato. –

5

soluzione di Manoj può causare un problema quando ci sono più tag per un evento.

L'unione interna SQL restituisce tutte le righe in modo che gli eventi possano avere risultati duplicati, la soluzione è aggiungere il metodo distinto.

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

Problemi correlati