From 6d4efa8e6a4cc7be4ba957dec71f6f63cd58700d Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Wed, 19 Dec 2018 23:04:25 +0000 Subject: [PATCH] Refs #28643 -- Changed Variance() to use NumericOutputFieldMixin. Keeps precision instead of forcing DecimalField to FloatField. --- django/db/models/aggregates.py | 5 ++--- docs/ref/models/querysets.txt | 5 +++-- docs/releases/2.2.txt | 6 +++--- tests/aggregation_regress/tests.py | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/django/db/models/aggregates.py b/django/db/models/aggregates.py index 9e4a71ef689..1b0f9d98af8 100644 --- a/django/db/models/aggregates.py +++ b/django/db/models/aggregates.py @@ -3,7 +3,7 @@ Classes to represent the definitions of aggregate functions. """ from django.core.exceptions import FieldError from django.db.models.expressions import Case, Func, Star, When -from django.db.models.fields import FloatField, IntegerField +from django.db.models.fields import IntegerField from django.db.models.functions.mixins import NumericOutputFieldMixin __all__ = [ @@ -172,9 +172,8 @@ class Sum(Aggregate): return super().as_sql(compiler, connection, **extra_context) -class Variance(Aggregate): +class Variance(NumericOutputFieldMixin, Aggregate): name = 'Variance' - output_field = FloatField() def __init__(self, expression, sample=False, **extra): self.function = 'VAR_SAMP' if sample else 'VAR_POP' diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index a80528220c2..3ddd516eafe 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -3419,12 +3419,13 @@ by the aggregate. ``Variance`` ~~~~~~~~~~~~ -.. class:: Variance(expression, sample=False, filter=None, **extra) +.. class:: Variance(expression, output_field=None, sample=False, filter=None, **extra) Returns the variance of the data in the provided expression. * Default alias: ``__variance`` - * 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 7323fd6e424..5d1333ad951 100644 --- a/docs/releases/2.2.txt +++ b/docs/releases/2.2.txt @@ -493,9 +493,9 @@ Miscellaneous * :djadmin:`runserver` no longer supports `pyinotify` (replaced by Watchman). -* 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``. +* The :class:`~django.db.models.Avg`, :class:`~django.db.models.StdDev`, and + :class:`~django.db.models.Variance` 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 d72e75ce324..274dc29d6dc 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -1160,7 +1160,7 @@ class AggregationTests(TestCase): self.assertEqual( Book.objects.aggregate(Variance('price')), - {'price__variance': Approximate(583.77, 1)} + {'price__variance': Approximate(Decimal('583.77'), 1)} ) self.assertEqual( @@ -1175,7 +1175,7 @@ class AggregationTests(TestCase): self.assertEqual( Book.objects.aggregate(Variance('price', sample=True)), - {'price__variance': Approximate(700.53, 2)} + {'price__variance': Approximate(Decimal('700.53'), 2)} ) def test_filtering_by_annotation_name(self):