diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2009-02-16 12:28:37 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2009-02-16 12:28:37 +0000 |
| commit | 58ea6d45618cb8b5bd4306c395d7bb8860f9a842 (patch) | |
| tree | 62c4bfe83ecff6ed7e5a7c0d8d1ef9d17803f127 /django/db/models/query.py | |
| parent | 88837875f245672a5e8671a1d144c78d3e102450 (diff) | |
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
Diffstat (limited to 'django/db/models/query.py')
| -rw-r--r-- | django/db/models/query.py | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py index c06a37897e..86fafc519d 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -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) |
