如何在django的queryset中查询子查询?

时间:2011-12-19 01:35:46

标签: python django

我怎么能在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')

但它不起作用,因为它返回两个输出......

5 个答案:

答案 0 :(得分:39)

如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/

答案 1 :(得分:19)

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

答案 2 :(得分:9)

您可以使用unevaluated queryset过滤主查询集,在Django中创建子查询。在你的情况下,它看起来像这样:

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

我假设您的PersonEmployee employee之间存在反向关系。我发现当我试图了解过滤器的工作原理时,查看查询集生成的SQL查询会很有帮助。

print people.query

正如其他人所说,你不需要为你的例子提供子查询。您可以加入员工表:

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

答案 3 :(得分:2)

您问题的正确答案在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]))

答案 4 :(得分:-1)

hero_qs = Hero.objects.filter(category=OuterRef("pk")).order_by("-benevolence_factor")
Category.objects.all().annotate(most_benevolent_hero=Subquery(hero_qs.values('name')[:1]))

生成的sql

SELECT "entities_category"."id",
       "entities_category"."name",
  (SELECT U0."name"
   FROM "entities_hero" U0
   WHERE U0."category_id" = ("entities_category"."id")
   ORDER BY U0."benevolence_factor" DESC
   LIMIT 1) AS "most_benevolent_hero"
FROM "entities_category"

有关更多详细信息,请参见this article