summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Kotler <mitchell.kotler@eprovenance.com>2015-07-15 17:29:33 -0400
committerTim Graham <timograham@gmail.com>2015-07-27 07:44:48 -0400
commit6024fd5dc2022f3724ea6440c319440d457a7366 (patch)
tree19e0207cc73961b686a59ea3c01936819a1207e1
parent199a02d1e2adef39b6346a254b097c9ac64a9ec4 (diff)
Fixed #25095 -- Fixed annotate() + values() group by bug
Thanks Josh Smeaton for help on the tests.
-rw-r--r--django/db/models/sql/query.py4
-rw-r--r--tests/aggregation/tests.py31
2 files changed, 33 insertions, 2 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index ba6a50a6f8..40ec57f9de 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1679,8 +1679,8 @@ class Query(object):
for col in self.select:
self.group_by.append(col)
- if self._annotations:
- for alias, annotation in six.iteritems(self.annotations):
+ if self.annotation_select:
+ for alias, annotation in six.iteritems(self.annotation_select):
for col in annotation.get_group_by_cols():
self.group_by.append(col)
diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py
index b98764537f..ad42aa3d77 100644
--- a/tests/aggregation/tests.py
+++ b/tests/aggregation/tests.py
@@ -395,6 +395,37 @@ class AggregateTestCase(TestCase):
vals = Book.objects.aggregate(Count("rating", distinct=True))
self.assertEqual(vals, {"rating__count": 4})
+ def test_non_grouped_annotation_not_in_group_by(self):
+ """
+ An annotation not included in values() before an aggregate should be
+ excluded from the group by clause.
+ """
+ qs = (
+ Book.objects.annotate(xprice=F('price')).filter(rating=4.0).values('rating')
+ .annotate(count=Count('publisher_id', distinct=True)).values('count', 'rating').order_by('count')
+ )
+ self.assertEqual(
+ list(qs), [
+ {'rating': 4.0, 'count': 2},
+ ]
+ )
+
+ def test_grouped_annotation_in_group_by(self):
+ """
+ An annotation included in values() before an aggregate should be
+ included in the group by clause.
+ """
+ qs = (
+ Book.objects.annotate(xprice=F('price')).filter(rating=4.0).values('rating', 'xprice')
+ .annotate(count=Count('publisher_id', distinct=True)).values('count', 'rating').order_by('count')
+ )
+ self.assertEqual(
+ list(qs), [
+ {'rating': 4.0, 'count': 1},
+ {'rating': 4.0, 'count': 2},
+ ]
+ )
+
def test_fkey_aggregate(self):
explicit = list(Author.objects.annotate(Count('book__id')))
implicit = list(Author.objects.annotate(Count('book')))