diff options
author | Boulder Sprinters <boulder-sprinters@djangoproject.com> | 2007-06-01 00:22:18 +0000 |
---|---|---|
committer | Boulder Sprinters <boulder-sprinters@djangoproject.com> | 2007-06-01 00:22:18 +0000 |
commit | 959343fc7e7f1b5c2e58a7890c848c172ad1fbbe (patch) | |
tree | ad90480372c2c48c758157a12fd61992a6f621ff | |
parent | bc8d41974dfd8097e6296c9706883306d8dd013a (diff) | |
download | django-959343fc7e7f1b5c2e58a7890c848c172ad1fbbe.tar.gz |
boulder-oracle-sprint: Merged [5385]. It got missed earlier.
git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@5396 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r-- | django/db/models/query.py | 23 | ||||
-rw-r--r-- | tests/modeltests/lookup/models.py | 21 |
2 files changed, 39 insertions, 5 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py index e3b9c794f8..40a110129e 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -566,9 +566,8 @@ else: 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: @@ -578,13 +577,27 @@ class ValuesQuerySet(QuerySet): # self._fields is a list of field names to fetch. if self._fields: - fields = [self.model._meta.get_field(f, many_to_many=False) for f in self._fields] + if not self._select: + fields = [self.model._meta.get_field(f, many_to_many=False) for f in self._fields] + else: + fields = [] + for f in self._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)) + 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. fields = self.model._meta.fields - columns = [f.column for f in fields] - field_names = [f.attname for f in fields] + field_names = [f.attname 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] + # 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) diff --git a/tests/modeltests/lookup/models.py b/tests/modeltests/lookup/models.py index c634aef8a1..6af70f8351 100644 --- a/tests/modeltests/lookup/models.py +++ b/tests/modeltests/lookup/models.py @@ -131,6 +131,27 @@ True [('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 |