Commit 6024fd5d authored by Mitchell Kotler's avatar Mitchell Kotler Committed by Tim Graham
Browse files

Fixed #25095 -- Fixed annotate() + values() group by bug

Thanks Josh Smeaton for help on the tests.
parent 199a02d1
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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)

+31 −0
Original line number Diff line number Diff line
@@ -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')))