我怎么能在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')
但它不起作用,因为它返回两个输出......
答案 0 :(得分:39)
如ypercube所述,您的用例不需要子查询。
但无论如何,因为很多人进入这个页面来学习如何进行子查询这里是如何完成的。
employee_query = Employee.objects.filter(company='Private').only('id').all()
Person.objects.value('name', 'age').filter(id__in=employee_query)
答案 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)
我假设您的Person
与Employee
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。