Author: jacob
Date: 2007-05-30 21:22:41 -0500 (Wed, 30 May 2007)
New Revision: 5385

Modified:
   django/trunk/django/db/models/query.py
   django/trunk/tests/modeltests/lookup/models.py
Log:
Fixed #3050: you can now use extra(select=...) with values(). Thanks, Honza Kral

Modified: django/trunk/django/db/models/query.py
===================================================================
--- django/trunk/django/db/models/query.py      2007-05-30 16:57:27 UTC (rev 
5384)
+++ django/trunk/django/db/models/query.py      2007-05-31 02:22:41 UTC (rev 
5385)
@@ -554,9 +554,8 @@
 class ValuesQuerySet(QuerySet):
     def __init__(self, *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 = {}
 
     def iterator(self):
         try:
@@ -566,13 +565,28 @@
 
         # self._fields is a list of field names to fetch.
         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
         else: # Default to all fields.
             columns = [f.column 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]
+
+        # 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.execute("SELECT " + (self._distinct and "DISTINCT " or "") + 
",".join(select) + sql, params)
         while 1:

Modified: django/trunk/tests/modeltests/lookup/models.py
===================================================================
--- django/trunk/tests/modeltests/lookup/models.py      2007-05-30 16:57:27 UTC 
(rev 5384)
+++ django/trunk/tests/modeltests/lookup/models.py      2007-05-31 02:22:41 UTC 
(rev 5385)
@@ -131,6 +131,27 @@
 [('headline', 'Article 7'), ('id', 7)]
 [('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
 >>> list(Article.objects.filter(id=5).values()) == [{'id': 5, 'headline': 
 >>> 'Article 5', 'pub_date': datetime(2005, 8, 1, 9, 0)}]
 True


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to