From e85afa5943695457c85e9bc1c5dc0d985004e303 Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Wed, 19 Dec 2018 23:03:42 +0000 Subject: [PATCH] Refs #28643 -- Changed StdDev() to use NumericOutputFieldMixin. Keeps precision instead of forcing DecimalField to FloatField. --- django/db/models/aggregates.py | 3 +-- docs/ref/models/querysets.txt | 5 +++-- docs/releases/2.2.txt | 5 +++-- tests/aggregation_regress/tests.py | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/django/db/models/aggregates.py b/django/db/models/aggregates.py index f9202543a3..9e4a71ef68 100644 --- a/django/db/models/aggregates.py +++ b/django/db/models/aggregates.py @@ -141,9 +141,8 @@ class Min(Aggregate): name = 'Min' -class StdDev(Aggregate): +class StdDev(NumericOutputFieldMixin, Aggregate): name = 'StdDev' - output_field = FloatField() def __init__(self, expression, sample=False, **extra): self.function = 'STDDEV_SAMP' if sample else 'STDDEV_POP' diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 46fcd50e37..a80528220c 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -3387,12 +3387,13 @@ by the aggregate. ``StdDev`` ~~~~~~~~~~ -.. class:: StdDev(expression, sample=False, filter=None, **extra) +.. class:: StdDev(expression, output_field=None, sample=False, filter=None, **extra) Returns the standard deviation of the data in the provided expression. * Default alias: ``__stddev`` - * Return type: ``float`` + * Return type: ``float`` if input is ``int``, otherwise same as input + field, or ``output_field`` if supplied Has one optional argument: diff --git a/docs/releases/2.2.txt b/docs/releases/2.2.txt index b96b0ed1ef..7323fd6e42 100644 --- a/docs/releases/2.2.txt +++ b/docs/releases/2.2.txt @@ -493,8 +493,9 @@ Miscellaneous * :djadmin:`runserver` no longer supports `pyinotify` (replaced by Watchman). -* The :class:`~django.db.models.Avg` aggregate function now returns a - ``Decimal`` instead of a ``float`` when the input is ``Decimal``. +* The :class:`~django.db.models.Avg` and :class:`~django.db.models.StdDev` + aggregate functions now return a ``Decimal`` instead of a ``float`` when the + input is ``Decimal``. .. _deprecated-features-2.2: diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index 64bbc13f80..d72e75ce32 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -1130,7 +1130,7 @@ class AggregationTests(TestCase): self.assertEqual( Book.objects.aggregate(StdDev('price')), - {'price__stddev': Approximate(24.16, 2)} + {'price__stddev': Approximate(Decimal('24.16'), 2)} ) self.assertEqual( @@ -1145,7 +1145,7 @@ class AggregationTests(TestCase): self.assertEqual( Book.objects.aggregate(StdDev('price', sample=True)), - {'price__stddev': Approximate(26.46, 1)} + {'price__stddev': Approximate(Decimal('26.46'), 1)} ) self.assertEqual(