mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	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:
		| @@ -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] | ||||||
|  |             if not self._select: | ||||||
|                 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] | ||||||
|  |             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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user