浏览代码

[5.0.x] Fixed #34975 -- Fixed crash of conditional aggregate() over aggregations.

Adjustments made to solve_lookup_type to defer the resolving of
references for summarized aggregates failed to account for similar
requirements for lookup values which can also reference annotations
through Aggregate.filter.

Regression in b181cae2e3697b2e53b5b67ac67e59f3b05a6f0d.

Refs #25307.

Thanks Sergey Nesterenko for the report.

Backport of 7530cf3900ab98104edcde69e8a2a415e82b345a from main
Simon Charette 1 年之前
父节点
当前提交
49f1ced863
共有 3 个文件被更改,包括 13 次插入2 次删除
  1. 3 2
      django/db/models/sql/query.py
  2. 4 0
      docs/releases/4.2.8.txt
  3. 6 0
      tests/aggregation/tests.py

+ 3 - 2
django/db/models/sql/query.py

@@ -1256,12 +1256,13 @@ class Query(BaseExpression):
             sql = "(%s)" % sql
         return sql, params
 
-    def resolve_lookup_value(self, value, can_reuse, allow_joins):
+    def resolve_lookup_value(self, value, can_reuse, allow_joins, summarize=False):
         if hasattr(value, "resolve_expression"):
             value = value.resolve_expression(
                 self,
                 reuse=can_reuse,
                 allow_joins=allow_joins,
+                summarize=summarize,
             )
         elif isinstance(value, (list, tuple)):
             # The items of the iterable may be expressions and therefore need
@@ -1487,7 +1488,7 @@ class Query(BaseExpression):
             raise FieldError("Joined field references are not permitted in this query")
 
         pre_joins = self.alias_refcount.copy()
-        value = self.resolve_lookup_value(value, can_reuse, allow_joins)
+        value = self.resolve_lookup_value(value, can_reuse, allow_joins, summarize)
         used_joins = {
             k for k, v in self.alias_refcount.items() if v > pre_joins.get(k, 0)
         }

+ 4 - 0
docs/releases/4.2.8.txt

@@ -11,3 +11,7 @@ Bugfixes
 
 * Fixed a regression in Django 4.2 that caused :option:`makemigrations --check`
   to stop displaying pending migrations (:ticket:`34457`).
+
+* Fixed a regression in Django 4.2 that caused a crash of
+  ``QuerySet.aggregate()`` with aggregates referencing other aggregates or
+  window functions through conditional expressions (:ticket:`34975`).

+ 6 - 0
tests/aggregation/tests.py

@@ -2300,3 +2300,9 @@ class AggregateAnnotationPruningTests(TestCase):
             aggregate,
             {"sum_avg_publisher_pages": 1100.0, "books_count": 2},
         )
+
+    def test_aggregate_reference_lookup_rhs(self):
+        aggregates = Author.objects.annotate(
+            max_book_author=Max("book__authors"),
+        ).aggregate(count=Count("id", filter=Q(id=F("max_book_author"))))
+        self.assertEqual(aggregates, {"count": 1})