diff options
| author | Mitchell Kotler <mitchell.kotler@eprovenance.com> | 2015-07-15 17:29:33 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-07-27 07:44:48 -0400 |
| commit | 6024fd5dc2022f3724ea6440c319440d457a7366 (patch) | |
| tree | 19e0207cc73961b686a59ea3c01936819a1207e1 | |
| parent | 199a02d1e2adef39b6346a254b097c9ac64a9ec4 (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.py | 4 | ||||
| -rw-r--r-- | tests/aggregation/tests.py | 31 |
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'))) |
