Refs #28643 -- Changed Variance() to use NumericOutputFieldMixin.

Keeps precision instead of forcing DecimalField to FloatField.
This commit is contained in:
Nick Pope 2018-12-19 23:04:25 +00:00 committed by Tim Graham
parent e85afa5943
commit 6d4efa8e6a
4 changed files with 10 additions and 10 deletions

View File

@ -3,7 +3,7 @@ Classes to represent the definitions of aggregate functions.
""" """
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from django.db.models.expressions import Case, Func, Star, When 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 from django.db.models.functions.mixins import NumericOutputFieldMixin
__all__ = [ __all__ = [
@ -172,9 +172,8 @@ class Sum(Aggregate):
return super().as_sql(compiler, connection, **extra_context) return super().as_sql(compiler, connection, **extra_context)
class Variance(Aggregate): class Variance(NumericOutputFieldMixin, Aggregate):
name = 'Variance' name = 'Variance'
output_field = FloatField()
def __init__(self, expression, sample=False, **extra): def __init__(self, expression, sample=False, **extra):
self.function = 'VAR_SAMP' if sample else 'VAR_POP' self.function = 'VAR_SAMP' if sample else 'VAR_POP'

View File

@ -3419,12 +3419,13 @@ by the aggregate.
``Variance`` ``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. Returns the variance of the data in the provided expression.
* Default alias: ``<field>__variance`` * Default alias: ``<field>__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: Has one optional argument:

View File

@ -493,9 +493,9 @@ Miscellaneous
* :djadmin:`runserver` no longer supports `pyinotify` (replaced by Watchman). * :djadmin:`runserver` no longer supports `pyinotify` (replaced by Watchman).
* The :class:`~django.db.models.Avg` and :class:`~django.db.models.StdDev` * The :class:`~django.db.models.Avg`, :class:`~django.db.models.StdDev`, and
aggregate functions now return a ``Decimal`` instead of a ``float`` when the :class:`~django.db.models.Variance` aggregate functions now return a
input is ``Decimal``. ``Decimal`` instead of a ``float`` when the input is ``Decimal``.
.. _deprecated-features-2.2: .. _deprecated-features-2.2:

View File

@ -1160,7 +1160,7 @@ class AggregationTests(TestCase):
self.assertEqual( self.assertEqual(
Book.objects.aggregate(Variance('price')), Book.objects.aggregate(Variance('price')),
{'price__variance': Approximate(583.77, 1)} {'price__variance': Approximate(Decimal('583.77'), 1)}
) )
self.assertEqual( self.assertEqual(
@ -1175,7 +1175,7 @@ class AggregationTests(TestCase):
self.assertEqual( self.assertEqual(
Book.objects.aggregate(Variance('price', sample=True)), 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): def test_filtering_by_annotation_name(self):