From c29e3092fdb1136f0945ce2be8f14c3853d6c8da Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 21 May 2025 16:16:12 +0200 Subject: [PATCH] [5.2.x] Fixed #36404 -- Fixed Aggregate.filter using OuterRef. Regression in a76035e925ff4e6d8676c65cb135c74b993b1039. Thank you to Simon Charette for the review. co-authored-by: Simon Charette Backport of b8e5a8a9a2a767f584cbe89a878a42363706f939 from main. --- django/db/models/aggregates.py | 5 ----- docs/releases/5.2.2.txt | 3 +++ tests/aggregation/test_filter_argument.py | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/django/db/models/aggregates.py b/django/db/models/aggregates.py index ea16cc440c..a3a07eb580 100644 --- a/django/db/models/aggregates.py +++ b/django/db/models/aggregates.py @@ -61,11 +61,6 @@ class Aggregate(Func): ): # Aggregates are not allowed in UPDATE queries, so ignore for_save c = super().resolve_expression(query, allow_joins, reuse, summarize) - c.filter = ( - c.filter.resolve_expression(query, allow_joins, reuse, summarize) - if c.filter - else None - ) if summarize: # Summarized aggregates cannot refer to summarized aggregates. for ref in c.get_refs(): diff --git a/docs/releases/5.2.2.txt b/docs/releases/5.2.2.txt index 2cf5c750ff..b8deb1c928 100644 --- a/docs/releases/5.2.2.txt +++ b/docs/releases/5.2.2.txt @@ -22,3 +22,6 @@ Bugfixes * Fixed a regression in Django 5.2 where subclasses of ``RemoteUserMiddleware`` that had overridden ``process_request()`` were no longer supported (:ticket:`36390`). + +* Fixed a regression in Django 5.2 that caused a crash when using ``OuterRef`` + in the ``filter`` argument of an ``Aggregate`` expression (:ticket:`36404`). diff --git a/tests/aggregation/test_filter_argument.py b/tests/aggregation/test_filter_argument.py index 75835edb0b..1a17703a86 100644 --- a/tests/aggregation/test_filter_argument.py +++ b/tests/aggregation/test_filter_argument.py @@ -84,6 +84,10 @@ class FilteredAggregateTests(TestCase): Author.objects.aggregate(age=agg)["age"], expected_result ) + def test_empty_filtered_aggregates(self): + agg = Count("pk", filter=Q()) + self.assertEqual(Author.objects.aggregate(count=agg)["count"], 3) + def test_double_filtered_aggregates(self): agg = Sum("age", filter=Q(Q(name="test2") & ~Q(name="test"))) self.assertEqual(Author.objects.aggregate(age=agg)["age"], 60) @@ -182,6 +186,23 @@ class FilteredAggregateTests(TestCase): ) self.assertEqual(aggregate, {"max_rating": 4.5}) + def test_filtered_aggregrate_ref_in_subquery_annotation(self): + aggs = ( + Author.objects.annotate( + count=Subquery( + Book.objects.annotate( + weird_count=Count( + "pk", + filter=Q(pages=OuterRef("age")), + ) + ).values("weird_count")[:1] + ), + ) + .order_by("pk") + .aggregate(sum=Sum("count")) + ) + self.assertEqual(aggs["sum"], 0) + def test_filtered_aggregate_on_exists(self): aggregate = Book.objects.values("publisher").aggregate( max_rating=Max(