Fixed bug with using values() and extra(select) in the same QuerySet, 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
This commit is contained in:
parent
8831f3ee2c
commit
5b8d2c9f0d
|
@ -579,28 +579,36 @@ class ValuesQuerySet(QuerySet):
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue