Skip to content

Commit

Permalink
Fixed bug with using values() and extra(select) in the same QuerySet,…
Browse files Browse the repository at this point in the history
… with a select dictionary containing more than a few elements. This bug was identified in unit test from [5767]. The problem was that we were relying on the dictionary's .items() ordering, which is undefined

git-svn-id: http://code.djangoproject.com/svn/django/trunk@5768 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
adrianholovaty committed Jul 27, 2007
1 parent 8831f3e commit 5b8d2c9
Showing 1 changed file with 17 additions and 9 deletions.
26 changes: 17 additions & 9 deletions django/db/models/query.py
Expand Up @@ -579,28 +579,36 @@ def iterator(self):
except EmptyResultSet: except EmptyResultSet:
raise StopIteration raise StopIteration


# self._fields is a list of field names to fetch. # self._select is a dictionary, and dictionaries' key order is
# undefined, so we convert it to a list of tuples.
extra_select = self._select.items()

# Construct two objects -- fields and field_names.
# fields is a list of Field objects to fetch.
# field_names is a list of field names, which will be the keys in the
# resulting dictionaries.
if self._fields: if self._fields:
if not self._select: if not extra_select:
fields = [self.model._meta.get_field(f, many_to_many=False) for f in self._fields] fields = [self.model._meta.get_field(f, many_to_many=False) for f in self._fields]
field_names = self._fields
else: else:
fields = [] fields = []
field_names = []
for f in self._fields: for f in self._fields:
if f in [field.name for field in self.model._meta.fields]: if f in [field.name for field in self.model._meta.fields]:
fields.append(self.model._meta.get_field(f, many_to_many=False)) fields.append(self.model._meta.get_field(f, many_to_many=False))
elif not self._select.has_key( f ): field_names.append(f)
raise FieldDoesNotExist, '%s has no field named %r' % ( self.model._meta.object_name, f ) elif not self._select.has_key(f):

raise FieldDoesNotExist('%s has no field named %r' % (self.model._meta.object_name, f))
field_names = self._fields
else: # Default to all fields. else: # Default to all fields.
fields = self.model._meta.fields fields = self.model._meta.fields
field_names = [f.attname for f in fields] field_names = [f.attname for f in fields]


columns = [f.column for f in fields] columns = [f.column for f in fields]
select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns] select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns]
# Add any additional SELECTs. if extra_select:
if self._select: select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in extra_select])
select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()]) field_names.extend([f[0] for f in extra_select])


cursor = connection.cursor() cursor = connection.cursor()
cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)
Expand Down

0 comments on commit 5b8d2c9

Please sign in to comment.