Как выполнить подзапрос в queryset в Django? - PullRequest
27 голосов
/ 19 декабря 2011

как мне получить подзапрос в наборе запросов django?например, если у меня есть:

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

это то, что я уже сделал.

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

но он не работает, потому что возвращает два вывода ...

Ответы [ 4 ]

40 голосов
/ 02 января 2014

как упомянуто ypercube, ваш вариант использования не требует подзапроса.

, но в любом случае, поскольку многие люди заходят на эту страницу, чтобы узнать, как выполнить подзапрос, вот как это делается.

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

Источник: http://mattrobenolt.com/the-django-orm-and-subqueries/

18 голосов
/ 19 декабря 2011
ids = Employee.objects.filter(company='Private').values_list('id', flat=True)
Person.objects.filter(id__in=ids).values('name', 'age')
9 голосов
/ 18 февраля 2015

Вы можете создавать подзапросы в Django, используя неоцененный набор запросов для фильтрации основного набора запросов. В вашем случае это будет выглядеть примерно так:

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

Я предполагаю, что у вас обратная связь от Person до Employee с именем employee. Мне было полезно посмотреть на SQL-запрос, сгенерированный набором запросов, когда я пытался понять, как работают фильтры.

print people.query

Как уже говорили другие, вам не нужен подзапрос для вашего примера. Вы можете просто присоединиться к таблице сотрудников:

people2 = Person.objects.filter(employee__company='Private')
3 голосов
/ 13 марта 2019

Правильный ответ на ваш вопрос здесь https://docs.djangoproject.com/en/2.1/ref/models/expressions/#subquery-expressions

Как пример:

>>> from django.db.models import OuterRef, Subquery
>>> newest = Comment.objects.filter(post=OuterRef('pk')).order_by('-created_at')
>>> Post.objects.annotate(newest_commenter_email=Subquery(newest.values('email')[:1]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...