Fixed #28459 -- Improved performance of ValuesListIterable.
This commit is contained in:
parent
32d1bf2bdb
commit
2d136ede8a
|
@ -3,6 +3,7 @@ The main QuerySet implementation. This provides the public API for the ORM.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
import operator
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from collections import OrderedDict, deque
|
from collections import OrderedDict, deque
|
||||||
|
@ -116,10 +117,8 @@ class ValuesListIterable(BaseIterable):
|
||||||
query = queryset.query
|
query = queryset.query
|
||||||
compiler = query.get_compiler(queryset.db)
|
compiler = query.get_compiler(queryset.db)
|
||||||
|
|
||||||
if not query.extra_select and not query.annotation_select:
|
results = compiler.results_iter()
|
||||||
for row in compiler.results_iter():
|
if queryset._fields:
|
||||||
yield tuple(row)
|
|
||||||
else:
|
|
||||||
field_names = list(query.values_select)
|
field_names = list(query.values_select)
|
||||||
extra_names = list(query.extra_select)
|
extra_names = list(query.extra_select)
|
||||||
annotation_names = list(query.annotation_select)
|
annotation_names = list(query.annotation_select)
|
||||||
|
@ -127,15 +126,13 @@ class ValuesListIterable(BaseIterable):
|
||||||
# extra(select=...) cols are always at the start of the row.
|
# extra(select=...) cols are always at the start of the row.
|
||||||
names = extra_names + field_names + annotation_names
|
names = extra_names + field_names + annotation_names
|
||||||
|
|
||||||
if queryset._fields:
|
fields = list(queryset._fields) + [f for f in annotation_names if f not in queryset._fields]
|
||||||
|
if fields != names:
|
||||||
# Reorder according to fields.
|
# Reorder according to fields.
|
||||||
fields = list(queryset._fields) + [f for f in annotation_names if f not in queryset._fields]
|
index_map = {name: idx for idx, name in enumerate(names)}
|
||||||
else:
|
rowfactory = operator.itemgetter(*[index_map[f] for f in fields])
|
||||||
fields = names
|
results = map(rowfactory, results)
|
||||||
|
return results
|
||||||
for row in compiler.results_iter():
|
|
||||||
data = dict(zip(names, row))
|
|
||||||
yield tuple(data[f] for f in fields)
|
|
||||||
|
|
||||||
|
|
||||||
class FlatValuesListIterable(BaseIterable):
|
class FlatValuesListIterable(BaseIterable):
|
||||||
|
|
Loading…
Reference in New Issue