mirror of
https://github.com/django/django.git
synced 2025-09-26 12:09:19 +00:00
Fixed #10256 -- Corrected the interaction of extra(select=) with values() and values_list() where an explicit list of columns is requested.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@9837 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
88837875f2
commit
58ea6d4561
3 changed files with 111 additions and 19 deletions
|
@ -727,12 +727,15 @@ class ValuesQuerySet(QuerySet):
|
|||
# names of the model fields to select.
|
||||
|
||||
def iterator(self):
|
||||
if (not self.extra_names and
|
||||
len(self.field_names) != len(self.model._meta.fields)):
|
||||
# Purge any extra columns that haven't been explicitly asked for
|
||||
if self.extra_names is not None:
|
||||
self.query.trim_extra_select(self.extra_names)
|
||||
names = self.query.extra_select.keys() + self.field_names
|
||||
names.extend(self.query.aggregate_select.keys())
|
||||
|
||||
extra_names = self.query.extra_select.keys()
|
||||
field_names = self.field_names
|
||||
aggregate_names = self.query.aggregate_select.keys()
|
||||
|
||||
names = extra_names + field_names + aggregate_names
|
||||
for row in self.query.results_iter():
|
||||
yield dict(zip(names, row))
|
||||
|
||||
|
@ -745,29 +748,30 @@ class ValuesQuerySet(QuerySet):
|
|||
instance.
|
||||
"""
|
||||
self.query.clear_select_fields()
|
||||
self.extra_names = []
|
||||
self.aggregate_names = []
|
||||
|
||||
if self._fields:
|
||||
self.extra_names = []
|
||||
self.aggregate_names = []
|
||||
if not self.query.extra_select and not self.query.aggregate_select:
|
||||
field_names = list(self._fields)
|
||||
self.field_names = list(self._fields)
|
||||
else:
|
||||
field_names = []
|
||||
self.query.default_cols = False
|
||||
self.field_names = []
|
||||
for f in self._fields:
|
||||
if self.query.extra_select.has_key(f):
|
||||
self.extra_names.append(f)
|
||||
elif self.query.aggregate_select.has_key(f):
|
||||
self.aggregate_names.append(f)
|
||||
else:
|
||||
field_names.append(f)
|
||||
self.field_names.append(f)
|
||||
else:
|
||||
# Default to all fields.
|
||||
field_names = [f.attname for f in self.model._meta.fields]
|
||||
self.extra_names = None
|
||||
self.field_names = [f.attname for f in self.model._meta.fields]
|
||||
self.aggregate_names = None
|
||||
|
||||
self.query.select = []
|
||||
self.query.add_fields(field_names, False)
|
||||
self.query.default_cols = False
|
||||
self.field_names = field_names
|
||||
self.query.add_fields(self.field_names, False)
|
||||
|
||||
def _clone(self, klass=None, setup=False, **kwargs):
|
||||
"""
|
||||
|
@ -817,7 +821,8 @@ class ValuesQuerySet(QuerySet):
|
|||
|
||||
class ValuesListQuerySet(ValuesQuerySet):
|
||||
def iterator(self):
|
||||
self.query.trim_extra_select(self.extra_names)
|
||||
if self.extra_names is not None:
|
||||
self.query.trim_extra_select(self.extra_names)
|
||||
if self.flat and len(self._fields) == 1:
|
||||
for row in self.query.results_iter():
|
||||
yield row[0]
|
||||
|
@ -825,13 +830,24 @@ class ValuesListQuerySet(ValuesQuerySet):
|
|||
for row in self.query.results_iter():
|
||||
yield tuple(row)
|
||||
else:
|
||||
# When extra(select=...) is involved, the extra cols come are
|
||||
# always at the start of the row, so we need to reorder the fields
|
||||
# When extra(select=...) or an annotation is involved, the extra cols are
|
||||
# always at the start of the row, and we need to reorder the fields
|
||||
# to match the order in self._fields.
|
||||
names = self.query.extra_select.keys() + self.field_names + self.query.aggregate_select.keys()
|
||||
extra_names = self.query.extra_select.keys()
|
||||
field_names = self.field_names
|
||||
aggregate_names = self.query.aggregate_select.keys()
|
||||
names = extra_names + field_names + aggregate_names
|
||||
|
||||
# If a field list has been specified, use it. Otherwise, use the
|
||||
# full list of fields, including extras and aggregates.
|
||||
if self._fields:
|
||||
fields = self._fields
|
||||
else:
|
||||
fields = names
|
||||
|
||||
for row in self.query.results_iter():
|
||||
data = dict(zip(names, row))
|
||||
yield tuple([data[f] for f in self._fields])
|
||||
yield tuple([data[f] for f in fields])
|
||||
|
||||
def _clone(self, *args, **kwargs):
|
||||
clone = super(ValuesListQuerySet, self)._clone(*args, **kwargs)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue