2011-12-19 10 views
23

come posso avere una sottoquery nel queryset di django? per esempio se ho:come subquery in queryset in django?

select name, age from person, employee where person.id = employee.id and 
employee.id in (select id from employee where employee.company = 'Private') 

questo è quello che ho già fatto.

Person.objects.value('name', 'age') 
Employee.objects.filter(company='Private') 

ma non funziona perché restituisce due uscite ...

+2

Il tuo esempio non è molto buono. Non hai bisogno di una subquery per questo: 'seleziona nome, età da persona, impiegato dove person.id = employee.id e employee.company = 'Private'' –

risposta

11
ids = Employee.objects.filter(company='Private').values_list('id', flat=True) 
Person.objects.filter(id__in=ids).values('name', 'age') 
+14

Questa non è una sottoquery,' values_list' non restituisce un set di query. Questo fa due query separate. –

+1

Non una sottoquery, solo due query. – Egg

+7

'values_list' restituisce un' ValuesQuerySet' e quelle due linee si tradurranno in una singola query con una sottoquery. – BBT

31

come menzionato da ypercube vostro caso d'uso non richiede sottoquery.

ma in ogni caso, dal momento che molte persone arrivano in questa pagina per imparare come eseguire la sub-query, ecco come è stato fatto.

employee_query = Employee.objects.filter(company='Private').only('id').all() 
Person.objects.value('name', 'age').filter(id__in=employee_query) 

Fonte: http://mattrobenolt.com/the-django-orm-and-subqueries/

+0

Menzionato su documenti: https://docs.djangoproject.com/en/1.9/ref/models/querysets/#in "può anche utilizzare un queryset per valutare dinamicamente l'elenco di valori invece di fornire un elenco di valori letterali:" e "Questo queryset sarà valutato come dichiarazione di subselect". –

6

È possibile creare sottoquery in Django utilizzando un unevaluated queryset per filtrare la tua set di query principale. Nel tuo caso, sarebbe simile a questa:

employee_query = Employee.objects.filter(company='Private') 
people = Person.objects.filter(employee__in=employee_query) 

sto supponendo che avete una relazione inversa Person-Employee nome employee. Ho trovato utile guardare la query SQL generata da un queryset quando stavo cercando di capire come funzionano i filtri.

print people.query 

Come altri hanno già detto, non è davvero necessaria una sottoquery per il proprio esempio. Potresti unirti al tavolo dei dipendenti:

people2 = Person.objects.filter(employee__company='Private') 
Problemi correlati