From 1fda238ce897e342402983e72a6226104141cc6d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 21 Jun 2010 20:28:47 +0000 Subject: [PATCH] [soc2010/query-refactor] Implemented values (and values_list). git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/query-refactor@13372 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/mongodb/compiler.py | 27 +++++++++++++++++----- django/db/models/query.py | 2 +- tests/regressiontests/mongodb/tests.py | 31 ++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/django/contrib/mongodb/compiler.py b/django/contrib/mongodb/compiler.py index 5ad09ae13c..7b3f382de1 100644 --- a/django/contrib/mongodb/compiler.py +++ b/django/contrib/mongodb/compiler.py @@ -56,16 +56,28 @@ class SQLCompiler(object): return {k: {"$not": v}} return {k: {"$ne": v}} - def build_query(self, aggregates=False): - assert len([a for a in self.query.alias_map if self.query.alias_refcount[a]]) <= 1 + def get_fields(self, aggregates): + if self.query.select: + fields = [] + for alias, field in self.query.select: + assert alias == self.query.model._meta.db_table + if field == self.query.model._meta.pk.column: + field = "_id" + fields.append(field) + return fields if not aggregates: assert self.query.default_cols + return None + + def build_query(self, aggregates=False): + assert len([a for a in self.query.alias_map if self.query.alias_refcount[a]]) <= 1 assert not self.query.distinct assert not self.query.extra assert not self.query.having filters = self.get_filters(self.query.where) - cursor = self.connection.db[self.query.model._meta.db_table].find(filters) + fields = self.get_fields(aggregates=aggregates) + cursor = self.connection.db[self.query.model._meta.db_table].find(filters, fields=fields) if self.query.order_by: cursor = cursor.sort([ (ordering.lstrip("-"), DESCENDING if ordering.startswith("-") else ASCENDING) @@ -79,10 +91,15 @@ class SQLCompiler(object): def results_iter(self): query = self.build_query() + fields = self.get_fields(aggregates=False) + if fields is None: + fields = [ + f.column if f is not self.query.model._meta.pk else "_id" + for f in self.query.model._meta.fields + ] for row in query: yield tuple( - row[f.column if f is not self.query.model._meta.pk else "_id"] - for f in self.query.model._meta.fields + row[f] for f in fields ) def has_results(self): diff --git a/django/db/models/query.py b/django/db/models/query.py index 958e8bdbc0..e43fc3150a 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -843,12 +843,12 @@ class ValuesQuerySet(QuerySet): if self._fields: self.extra_names = [] self.aggregate_names = [] + self.query.default_cols = False if not self.query.extra and not self.query.aggregates: # Short cut - if there are no extra or aggregates, then # the values() clause must be just field names. self.field_names = list(self._fields) else: - self.query.default_cols = False self.field_names = [] for f in self._fields: # we inspect the full extra_select list since we might diff --git a/tests/regressiontests/mongodb/tests.py b/tests/regressiontests/mongodb/tests.py index 0c3b74ef43..e8024c2d61 100644 --- a/tests/regressiontests/mongodb/tests.py +++ b/tests/regressiontests/mongodb/tests.py @@ -113,6 +113,37 @@ class MongoTestCase(TestCase): artists[2:], lambda a: a, ) + + def test_values(self): + a = Artist.objects.create(name="Steve Perry", good=True) + + self.assertQuerysetEqual( + Artist.objects.values(), [ + {"name": "Steve Perry", "good": True, "current_group_id": None, "id": a.pk}, + ], + lambda a: a, + ) + + self.assertQuerysetEqual( + Artist.objects.values("name"), [ + {"name": "Steve Perry"}, + ], + lambda a: a, + ) + + self.assertQuerysetEqual( + Artist.objects.values_list("name"), [ + ("Steve Perry",) + ], + lambda a: a, + ) + + self.assertQuerysetEqual( + Artist.objects.values_list("name", flat=True), [ + "Steve Perry", + ], + lambda a: a, + ) def test_not_equals(self): q = Group.objects.create(name="Queen", year_formed=1971)