summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/models/functions/mixins.py8
-rw-r--r--docs/releases/2.2.3.txt4
-rw-r--r--tests/aggregation/test_filter_argument.py15
3 files changed, 21 insertions, 6 deletions
diff --git a/django/db/models/functions/mixins.py b/django/db/models/functions/mixins.py
index 8486ddb005..636340f015 100644
--- a/django/db/models/functions/mixins.py
+++ b/django/db/models/functions/mixins.py
@@ -42,9 +42,9 @@ class FixDurationInputMixin:
class NumericOutputFieldMixin:
def _resolve_output_field(self):
- source_expressions = self.get_source_expressions()
- if any(isinstance(s.output_field, DecimalField) for s in source_expressions):
+ source_fields = self.get_source_fields()
+ if any(isinstance(s, DecimalField) for s in source_fields):
return DecimalField()
- if any(isinstance(s.output_field, IntegerField) for s in source_expressions):
+ if any(isinstance(s, IntegerField) for s in source_fields):
return FloatField()
- return super()._resolve_output_field() if source_expressions else FloatField()
+ return super()._resolve_output_field() if source_fields else FloatField()
diff --git a/docs/releases/2.2.3.txt b/docs/releases/2.2.3.txt
index 73dba08a83..a42e57c779 100644
--- a/docs/releases/2.2.3.txt
+++ b/docs/releases/2.2.3.txt
@@ -9,4 +9,6 @@ Django 2.2.3 fixes several bugs in 2.2.2.
Bugfixes
========
-* ...
+* Fixed a regression in Django 2.2 where :class:`~django.db.models.Avg`,
+ :class:`~django.db.models.StdDev`, and :class:`~django.db.models.Variance`
+ crash with ``filter`` argument (:ticket:`30542`).
diff --git a/tests/aggregation/test_filter_argument.py b/tests/aggregation/test_filter_argument.py
index 63dee59464..9d6c0a52af 100644
--- a/tests/aggregation/test_filter_argument.py
+++ b/tests/aggregation/test_filter_argument.py
@@ -1,8 +1,11 @@
import datetime
from decimal import Decimal
-from django.db.models import Case, Count, F, Q, Sum, When
+from django.db.models import (
+ Avg, Case, Count, F, Q, StdDev, Sum, Variance, When,
+)
from django.test import TestCase
+from django.test.utils import Approximate
from .models import Author, Book, Publisher
@@ -40,6 +43,16 @@ class FilteredAggregateTests(TestCase):
agg = Sum('age', filter=Q(name__startswith='test'))
self.assertEqual(Author.objects.aggregate(age=agg)['age'], 200)
+ def test_filtered_numerical_aggregates(self):
+ for aggregate, expected_result in (
+ (Avg, Approximate(66.7, 1)),
+ (StdDev, Approximate(24.9, 1)),
+ (Variance, Approximate(622.2, 1)),
+ ):
+ with self.subTest(aggregate=aggregate.__name__):
+ agg = aggregate('age', filter=Q(name__startswith='test'))
+ self.assertEqual(Author.objects.aggregate(age=agg)['age'], expected_result)
+
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)