how to subquery in queryset in django?

后端 未结 5 1594
予麋鹿
予麋鹿 2020-12-14 00:49

how can i have a subquery in django\'s queryset? for example if i have:

select name, age from person, employee where person.id = employee.id and
employee.id          


        
相关标签:
5条回答
  • 2020-12-14 01:21
    ids = Employee.objects.filter(company='Private').values_list('id', flat=True)
    Person.objects.filter(id__in=ids).values('name', 'age')
    
    0 讨论(0)
  • 2020-12-14 01:25

    as mentioned by ypercube your use case doesn't require subquery.

    but anyway since many people land into this page to learn how to do sub-query here is how its done.

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

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

    0 讨论(0)
  • 2020-12-14 01:36

    You can create subqueries in Django by using an unevaluated queryset to filter your main queryset. In your case, it would look something like this:

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

    I'm assuming that you have a reverse relationship from Person to Employee named employee. I found it helpful to look at the SQL query generated by a queryset when I was trying to understand how the filters work.

    print people.query
    

    As others have said, you don't really need a subquery for your example. You could just join to the employee table:

    people2 = Person.objects.filter(employee__company='Private')
    
    0 讨论(0)
  • 2020-12-14 01:41
    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]))
    

    the generated 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"
    

    For more details, see this article.

    0 讨论(0)
  • 2020-12-14 01:46

    The correct answer on your question is here https://docs.djangoproject.com/en/2.1/ref/models/expressions/#subquery-expressions

    As an example:

    >>> 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]))
    
    0 讨论(0)
提交回复
热议问题