summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2022-01-31 11:33:24 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-01-31 11:34:29 +0100
commitaff79be03a8c787ba0cc7e00dcec9eeb8ad01c87 (patch)
tree8b60ea9252f26dc4d82c810beca15e0a855635b2
parent7a1c6533eb72c3e6faa308796ba7f8d7d447d3b9 (diff)
downloaddjango-aff79be03a8c787ba0cc7e00dcec9eeb8ad01c87.tar.gz
[4.0.x] Fixed #33468 -- Fixed QuerySet.aggregate() after annotate() crash on aggregates with default.
Thanks Adam Johnson for the report. Backport of 71e7c8e73712419626f1c2b6ec036e8559a2d667 from main
-rw-r--r--django/db/models/aggregates.py4
-rw-r--r--docs/releases/4.0.2.txt4
-rw-r--r--tests/aggregation/tests.py12
3 files changed, 19 insertions, 1 deletions
diff --git a/django/db/models/aggregates.py b/django/db/models/aggregates.py
index 596a161669..19d7938bdb 100644
--- a/django/db/models/aggregates.py
+++ b/django/db/models/aggregates.py
@@ -65,7 +65,9 @@ class Aggregate(Func):
if hasattr(default, 'resolve_expression'):
default = default.resolve_expression(query, allow_joins, reuse, summarize)
c.default = None # Reset the default argument before wrapping.
- return Coalesce(c, default, output_field=c._output_field_or_none)
+ coalesce = Coalesce(c, default, output_field=c._output_field_or_none)
+ coalesce.is_summary = c.is_summary
+ return coalesce
@property
def default_alias(self):
diff --git a/docs/releases/4.0.2.txt b/docs/releases/4.0.2.txt
index c60dc68224..e7b9879625 100644
--- a/docs/releases/4.0.2.txt
+++ b/docs/releases/4.0.2.txt
@@ -33,3 +33,7 @@ Bugfixes
* Fixed a duplicate operation regression in Django 4.0 that caused a migration
crash when altering a primary key type for a concrete parent model referenced
by a foreign key (:ticket:`33462`).
+
+* Fixed a bug in Django 4.0 that caused a crash of ``QuerySet.aggregate()``
+ after ``annotate()`` on an aggregate function with a
+ :ref:`default <aggregate-default>` (:ticket:`33468`).
diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py
index 72575a526c..68d3c4d31e 100644
--- a/tests/aggregation/tests.py
+++ b/tests/aggregation/tests.py
@@ -1604,6 +1604,18 @@ class AggregateTestCase(TestCase):
)
self.assertAlmostEqual(result['value'], Decimal('61.72'), places=2)
+ def test_aggregation_default_after_annotation(self):
+ result = Publisher.objects.annotate(
+ double_num_awards=F('num_awards') * 2,
+ ).aggregate(value=Sum('double_num_awards', default=0))
+ self.assertEqual(result['value'], 40)
+
+ def test_aggregation_default_not_in_aggregate(self):
+ result = Publisher.objects.annotate(
+ avg_rating=Avg('book__rating', default=2.5),
+ ).aggregate(Sum('num_awards'))
+ self.assertEqual(result['num_awards__sum'], 20)
+
def test_exists_none_with_aggregate(self):
qs = Book.objects.all().annotate(
count=Count('id'),