Commit 4bd55547 authored by Anssi Kääriäinen's avatar Anssi Kääriäinen
Browse files

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.
parent 29a09b36
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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)
            aggregate_names.append(alias)
        query.append_aggregate_mask(aggregate_names)

        return query.get_aggregation(using=self.db)

+4 −0
Original line number Diff line number Diff line
@@ -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,
+11 −0
Original line number Diff line number Diff line
@@ -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})