Connor Meeks
Connor Meeks

Reputation: 501

Django: Loop Queryset inside Queryset

So I have queryset1 that filters ModelA by 2 parameters:

queryset1 = ModelA.objects.all().filter(par1="X",par2="Y")

Then I have another queryset2 that I would like to filter ModelB by grabbing the elements that have already been filtered by queryset1, and also that follow another parameter:

queryset2 = ModelB.objects.all().filter(par3="X" for i in queryset,par4="Z")

My question is: Is there a way to perform a queryset on a queryset that you have already made? In the end I would like to pull the objects from ModelA and ModelB that follow par1 par2 par3. How would I do this?

Upvotes: 0

Views: 977

Answers (2)

e4c5
e4c5

Reputation: 53734

it's quite possible to achieve without a for loop. The disadvantage of using a for loop is that you are actually executing two queries and retrieving the results for the first one. If that happens to produce a large number of rows you are burning up resources and slowing down the response time.

queryset2 = ModelB.objects.all().filter(par3__in=queryset,par4="Z")

This would result in a subquery as explained at https://docs.djangoproject.com/en/1.9/ref/models/querysets/

You can also use a queryset to dynamically evaluate the list of values instead of providing a list of literal values:

SELECT * FROM app_modelb where par3 IN (SELECT ...)

Upvotes: 1

Todor
Todor

Reputation: 16010

What you can do is:

  1. When par3 is a relation of the same type of the queryset1:

    queryset2 = ModelB.objects.all().filter(par3__in=queryset1, par4="Z")
    
  2. Use the values_list('some_field', flat=True) notation, when part3 is not a relation

    queryset2 = ModelB.objects.all().filter(par3__in=queryset1.values_list('X', flat=True), par4="Z")
    

Upvotes: 1

Related Questions