Django ORM values_list with __in 'filter characteristic

What is the preferred way to filter a request given with '__in' in Django?

providers = Provider.objects.filter(age__gt=10)
consumers = Consumer.objects.filter(consumer__in=providers)

      

or

providers_ids = Provider.objects.filter(age__gt=10).values_list('id', flat=True)
consumers = Consumer.objects.filter(consumer__in=providers_ids)

      

+3


source to share


2 answers


They must be completely equivalent. Under the hood, Django will optimize both of these for a subquery query in SQL. See the QuerySet APIin

reference at :

This query will be evaluated as a subquery operator:

SELECT ... WHERE consumer.id IN (SELECT id FROM ... WHERE _ IN _)

      



However, you can force a search based on passing explicit values ​​for primary keys by calling list

on yours values_list

, for example:

providers_ids = list(Provider.objects.filter(age__gt=10).values_list('id', flat=True))
consumers = Consumer.objects.filter(consumer__in=providers_ids)

      

This may be more efficient in some cases, such as when you have few vendors, but that will depend entirely on your data and what database you are using. See the "Performance Recommendations" note in the above link.

+7


source


I agree with Vilduk. However, a few notes

You can combine a filter like this:

consumers = Consumer.objects.filter(consumer__age__gt=10)

      

This will give you the same set of results - in one query.



Second, you can use the sentence .query

at the end to parse the generated query .

Example:

print Provider.objects.filter(age__gt=10).query

      

will print the query that the ORM will generate to get the result set.

+4


source







All Articles