2011-12-19 15 views
23

Jak mogę wykonać podzapytanie w zapytaniu Django? na przykład, jeśli mam:jak dokonać podzapytania w zapytaniu w django?

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

to jest to, co jeszcze zrobiłem.

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

ale to nie działa, ponieważ zwraca dwa wyjścia ...

+2

Twój przykład nie jest zbyt dobry. Nie potrzebujesz podzapytania dla tego: 'wybierz nazwę, wiek od osoby, pracownika gdzie person.id = employee.id i employee.company = 'Private'' –

Odpowiedz

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

To nie jest podzapytanie,' values_list' nie zwraca queryset. To powoduje dwa oddzielne zapytania. –

+1

Brak podkwerendy, tylko dwa zapytania. – Egg

+7

'values_list' zwraca' ValuesQuerySet', a te dwie linie będą faktycznie tłumaczone na pojedyncze zapytanie z podzapytaniem. – BBT

31

jak wspomniano przez ypercube przypadku użycia nie wymaga podzapytania.

ale w każdym razie, ponieważ wiele osób ląduje na tej stronie, aby dowiedzieć się, jak wykonać sub-zapytanie, oto jak to się robi.

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

Źródło: http://mattrobenolt.com/the-django-orm-and-subqueries/

+0

Wymienione w dokumentach: https://docs.djangoproject.com/en/1.9/ref/models/querysets/#in "można również użyć zestawu zapytań do dynamicznej oceny listy wartości zamiast podawania listy wartości literałów:" i "Ten zestaw zapytań zostanie oceniony jako instrukcja podsekcji". –

6

Można tworzyć podzapytania w Django przy użyciu unevaluated queryset filtrować queryset głównego. W twoim przypadku, to będzie wyglądać mniej więcej tak:

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

Jestem zakładając, że masz odwrotną zależność od Person do Employee nazwie employee. Zauważyłem, że warto przyjrzeć się zapytaniu SQL wygenerowanemu przez zestaw zapytań, gdy próbowałem zrozumieć, jak działają filtry.

print people.query 

Jak powiedzieli inni, tak naprawdę nie potrzebujesz podzapytania dla twojego przykładu. Możesz po prostu dołączyć do tabeli pracowników:

people2 = Person.objects.filter(employee__company='Private') 
Powiązane problemy