summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2013-07-23 11:38:38 +0300
committerAnssi Kääriäinen <akaariai@gmail.com>2013-07-23 11:38:38 +0300
commit4bd55547214ae149acadffe60536c379d51e318f (patch)
tree0b2235ec303a75e6aeaed084be90762e9f8a16b8
parent29a09b3638e625458b5e07ed0956451432421acf (diff)
Fixed #20782 -- qs.values().aggregate() failure
In the combination of .values().aggregate() the aggregate_select_mask didn't include the aggregates added. This resulted in bogus query. Thanks to Trac alias debanshuk for report.
-rw-r--r--django/db/models/query.py5
-rw-r--r--django/db/models/sql/query.py4
-rw-r--r--tests/aggregation/tests.py11
3 files changed, 19 insertions, 1 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 811e917764..9dcf620448 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -274,9 +274,12 @@ class QuerySet(object):
query = self.query.clone()
+ aggregate_names = []
for (alias, aggregate_expr) in kwargs.items():
query.add_aggregate(aggregate_expr, self.model, alias,
- is_summary=True)
+ is_summary=True)
+ aggregate_names.append(alias)
+ query.append_aggregate_mask(aggregate_names)
return query.get_aggregation(using=self.db)
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 2a9b8ef826..da0c39e1e7 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1753,6 +1753,10 @@ class Query(object):
self.aggregate_select_mask = set(names)
self._aggregate_select_cache = None
+ def append_aggregate_mask(self, names):
+ if self.aggregate_select_mask is not None:
+ self.set_aggregate_mask(set(names).union(self.aggregate_select_mask))
+
def set_extra_mask(self, names):
"""
Set the mask of extra select items that will be returned by SELECT,
diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py
index c635e6ebb6..dd7e994a63 100644
--- a/tests/aggregation/tests.py
+++ b/tests/aggregation/tests.py
@@ -585,3 +585,14 @@ class BaseAggregateTestCase(TestCase):
"datetime.date(2008, 1, 1)"
]
)
+
+ def test_values_aggregation(self):
+ # Refs #20782
+ max_rating = Book.objects.values('rating').aggregate(max_rating=Max('rating'))
+ self.assertEqual(max_rating['max_rating'], 5)
+ max_books_per_rating = Book.objects.values('rating').annotate(
+ books_per_rating=Count('id')
+ ).aggregate(Max('books_per_rating'))
+ self.assertEqual(
+ max_books_per_rating,
+ {'books_per_rating__max': 3})