Fixed #3050: you can now use extra(select=...) with values(). Thanks, Honza Kral
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5385 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
f2aaa3d1d1
commit
bf2e62aa3c
|
@ -554,9 +554,8 @@ class QuerySet(object):
|
||||||
class ValuesQuerySet(QuerySet):
|
class ValuesQuerySet(QuerySet):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(ValuesQuerySet, self).__init__(*args, **kwargs)
|
super(ValuesQuerySet, self).__init__(*args, **kwargs)
|
||||||
# select_related and select aren't supported in values().
|
# select_related isn't supported in values().
|
||||||
self._select_related = False
|
self._select_related = False
|
||||||
self._select = {}
|
|
||||||
|
|
||||||
def iterator(self):
|
def iterator(self):
|
||||||
try:
|
try:
|
||||||
|
@ -566,13 +565,28 @@ class ValuesQuerySet(QuerySet):
|
||||||
|
|
||||||
# self._fields is a list of field names to fetch.
|
# self._fields is a list of field names to fetch.
|
||||||
if self._fields:
|
if self._fields:
|
||||||
columns = [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields]
|
#columns = [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields]
|
||||||
|
if not self._select:
|
||||||
|
columns = [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields]
|
||||||
|
else:
|
||||||
|
columns = []
|
||||||
|
for f in self._fields:
|
||||||
|
if f in [field.name for field in self.model._meta.fields]:
|
||||||
|
columns.append( self.model._meta.get_field(f, many_to_many=False).column )
|
||||||
|
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
|
field_names = self._fields
|
||||||
else: # Default to all fields.
|
else: # Default to all fields.
|
||||||
columns = [f.column for f in self.model._meta.fields]
|
columns = [f.column for f in self.model._meta.fields]
|
||||||
field_names = [f.attname for f in self.model._meta.fields]
|
field_names = [f.attname for f in self.model._meta.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 self._select:
|
||||||
|
select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()])
|
||||||
|
|
||||||
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)
|
||||||
while 1:
|
while 1:
|
||||||
|
|
|
@ -131,6 +131,27 @@ True
|
||||||
[('headline', 'Article 7'), ('id', 7)]
|
[('headline', 'Article 7'), ('id', 7)]
|
||||||
[('headline', 'Article 1'), ('id', 1)]
|
[('headline', 'Article 1'), ('id', 1)]
|
||||||
|
|
||||||
|
|
||||||
|
# you can use values() even on extra fields
|
||||||
|
>>> for d in Article.objects.extra( select={'id_plus_one' : 'id + 1'} ).values('id', 'id_plus_one'):
|
||||||
|
... i = d.items()
|
||||||
|
... i.sort()
|
||||||
|
... i
|
||||||
|
[('id', 5), ('id_plus_one', 6)]
|
||||||
|
[('id', 6), ('id_plus_one', 7)]
|
||||||
|
[('id', 4), ('id_plus_one', 5)]
|
||||||
|
[('id', 2), ('id_plus_one', 3)]
|
||||||
|
[('id', 3), ('id_plus_one', 4)]
|
||||||
|
[('id', 7), ('id_plus_one', 8)]
|
||||||
|
[('id', 1), ('id_plus_one', 2)]
|
||||||
|
|
||||||
|
# however, an exception FieldDoesNotExist will still be thrown
|
||||||
|
# if you try to access non-existent field (field that is neither on the model nor extra)
|
||||||
|
>>> Article.objects.extra( select={'id_plus_one' : 'id + 1'} ).values('id', 'id_plus_two')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
FieldDoesNotExist: Article has no field named 'id_plus_two'
|
||||||
|
|
||||||
# if you don't specify which fields, all are returned
|
# if you don't specify which fields, all are returned
|
||||||
>>> list(Article.objects.filter(id=5).values()) == [{'id': 5, 'headline': 'Article 5', 'pub_date': datetime(2005, 8, 1, 9, 0)}]
|
>>> list(Article.objects.filter(id=5).values()) == [{'id': 5, 'headline': 'Article 5', 'pub_date': datetime(2005, 8, 1, 9, 0)}]
|
||||||
True
|
True
|
||||||
|
|
Loading…
Reference in New Issue