Edgar Navasardyan
Edgar Navasardyan

Reputation: 4511

Django - getting list of values after annotating a queryset

I have a Django code like this:

max_id_qs = qs1.values('parent__id').\
                       annotate(max_id = Max('id'),).\
               values_list('max_id', flat = True)

The problem is that when I use max_id_qs in a filter like this:

rs = qs2.filter(id__in = max_id_qs)

the query transforms into a MySQL query of the following structure:

select ... from ... where ... and id in (select max(id) from ...)

whereas the intended result should be

select ... from ... where ... and id in [2342, 233, 663, ...]

In other words, I get subquery instead of list of integers in the MySQL query which slows down the lookup dramatically. What surprises me is that I thought that Django's values_list returns a list of values.

So the question, how should I rewrite the code to achieve the desired MySQL query with integers instead of id in (select ... from...) subquery

Upvotes: 1

Views: 1607

Answers (1)

Antash
Antash

Reputation: 998

Querysets are lazy, and .values_list still returns a queryset object. To evaluate it simply convert it into a list:

rs = qs2.filter(id__in=list(max_id_qs))

Upvotes: 1

Related Questions