diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index ef55dbe3a94..2ffcfaa10cc 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -453,6 +453,9 @@ class Query(BaseExpression): # filtering against window functions is involved as it # requires complex realising. annotation_mask = set() + if isinstance(self.group_by, tuple): + for expr in self.group_by: + annotation_mask |= expr.get_refs() for aggregate in aggregates.values(): annotation_mask |= aggregate.get_refs() inner_query.set_annotation_mask(annotation_mask) diff --git a/docs/releases/4.2.1.txt b/docs/releases/4.2.1.txt index c768b98b18b..f8a4edf7878 100644 --- a/docs/releases/4.2.1.txt +++ b/docs/releases/4.2.1.txt @@ -15,3 +15,6 @@ Bugfixes * Fixed a regression in Django 4.2 that caused a crash of :class:`~django.contrib.postgres.search.SearchVector` function with ``%`` characters (:ticket:`34459`). + +* Fixed a regression in Django 4.2 that caused aggregation over query that + uses explicit grouping to group against the wrong columns (:ticket:`34464`). diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py index c1ae9f0dd52..ae68c245634 100644 --- a/tests/aggregation/tests.py +++ b/tests/aggregation/tests.py @@ -36,6 +36,7 @@ from django.db.models.functions import ( Greatest, Least, Lower, + Mod, Now, Pi, TruncDate, @@ -2175,3 +2176,9 @@ class AggregateAnnotationPruningTests(TestCase): sql = ctx.captured_queries[0]["sql"].lower() self.assertEqual(sql.count("select"), 2, "Subquery wrapping required") self.assertEqual(sql.count("authors_count"), 2) + + def test_referenced_group_by_annotation_kept(self): + queryset = Book.objects.values(pages_mod=Mod("pages", 10)).annotate( + mod_count=Count("*") + ) + self.assertEqual(queryset.count(), 1)