mirror of https://github.com/django/django.git
Fixed #30665 -- Added support for distinct argument to Avg() and Sum().
This commit is contained in:
parent
cb3c2da128
commit
5f24e7158e
|
@ -99,6 +99,7 @@ class Aggregate(Func):
|
||||||
class Avg(FixDurationInputMixin, NumericOutputFieldMixin, Aggregate):
|
class Avg(FixDurationInputMixin, NumericOutputFieldMixin, Aggregate):
|
||||||
function = 'AVG'
|
function = 'AVG'
|
||||||
name = 'Avg'
|
name = 'Avg'
|
||||||
|
allow_distinct = True
|
||||||
|
|
||||||
|
|
||||||
class Count(Aggregate):
|
class Count(Aggregate):
|
||||||
|
@ -142,6 +143,7 @@ class StdDev(NumericOutputFieldMixin, Aggregate):
|
||||||
class Sum(FixDurationInputMixin, Aggregate):
|
class Sum(FixDurationInputMixin, Aggregate):
|
||||||
function = 'SUM'
|
function = 'SUM'
|
||||||
name = 'Sum'
|
name = 'Sum'
|
||||||
|
allow_distinct = True
|
||||||
|
|
||||||
|
|
||||||
class Variance(NumericOutputFieldMixin, Aggregate):
|
class Variance(NumericOutputFieldMixin, Aggregate):
|
||||||
|
|
|
@ -3378,7 +3378,7 @@ by the aggregate.
|
||||||
``Avg``
|
``Avg``
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
.. class:: Avg(expression, output_field=None, filter=None, **extra)
|
.. class:: Avg(expression, output_field=None, distinct=False, filter=None, **extra)
|
||||||
|
|
||||||
Returns the mean value of the given expression, which must be numeric
|
Returns the mean value of the given expression, which must be numeric
|
||||||
unless you specify a different ``output_field``.
|
unless you specify a different ``output_field``.
|
||||||
|
@ -3387,6 +3387,18 @@ by the aggregate.
|
||||||
* Return type: ``float`` if input is ``int``, otherwise same as input
|
* Return type: ``float`` if input is ``int``, otherwise same as input
|
||||||
field, or ``output_field`` if supplied
|
field, or ``output_field`` if supplied
|
||||||
|
|
||||||
|
Has one optional argument:
|
||||||
|
|
||||||
|
.. attribute:: distinct
|
||||||
|
|
||||||
|
If ``distinct=True``, ``Avg`` returns the mean value of unique values.
|
||||||
|
This is the SQL equivalent of ``AVG(DISTINCT <field>)``. The default
|
||||||
|
value is ``False``.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.0
|
||||||
|
|
||||||
|
Support for ``distinct=True`` was added.
|
||||||
|
|
||||||
``Count``
|
``Count``
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
|
@ -3451,13 +3463,25 @@ by the aggregate.
|
||||||
``Sum``
|
``Sum``
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
.. class:: Sum(expression, output_field=None, filter=None, **extra)
|
.. class:: Sum(expression, output_field=None, distinct=False, filter=None, **extra)
|
||||||
|
|
||||||
Computes the sum of all values of the given expression.
|
Computes the sum of all values of the given expression.
|
||||||
|
|
||||||
* Default alias: ``<field>__sum``
|
* Default alias: ``<field>__sum``
|
||||||
* Return type: same as input field, or ``output_field`` if supplied
|
* Return type: same as input field, or ``output_field`` if supplied
|
||||||
|
|
||||||
|
Has one optional argument:
|
||||||
|
|
||||||
|
.. attribute:: distinct
|
||||||
|
|
||||||
|
If ``distinct=True``, ``Sum`` returns the sum of unique values. This is
|
||||||
|
the SQL equivalent of ``SUM(DISTINCT <field>)``. The default value is
|
||||||
|
``False``.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.0
|
||||||
|
|
||||||
|
Support for ``distinct=True`` was added.
|
||||||
|
|
||||||
``Variance``
|
``Variance``
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -291,6 +291,9 @@ Models
|
||||||
customize the get and set behavior by overriding their
|
customize the get and set behavior by overriding their
|
||||||
:py:ref:`descriptors <descriptors>`.
|
:py:ref:`descriptors <descriptors>`.
|
||||||
|
|
||||||
|
* :class:`~django.db.models.Avg` and :class:`~django.db.models.Sum` now support
|
||||||
|
the ``distinct`` argument.
|
||||||
|
|
||||||
Requests and Responses
|
Requests and Responses
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -401,8 +401,14 @@ class AggregateTestCase(TestCase):
|
||||||
self.assertEqual(aggs['distinct_ratings'], 4)
|
self.assertEqual(aggs['distinct_ratings'], 4)
|
||||||
|
|
||||||
def test_distinct_on_aggregate(self):
|
def test_distinct_on_aggregate(self):
|
||||||
books = Book.objects.aggregate(ratings=Count('rating', distinct=True))
|
for aggregate, expected_result in (
|
||||||
self.assertEqual(books['ratings'], 4)
|
(Avg, 4.125),
|
||||||
|
(Count, 4),
|
||||||
|
(Sum, 16.5),
|
||||||
|
):
|
||||||
|
with self.subTest(aggregate=aggregate.__name__):
|
||||||
|
books = Book.objects.aggregate(ratings=aggregate('rating', distinct=True))
|
||||||
|
self.assertEqual(books['ratings'], expected_result)
|
||||||
|
|
||||||
def test_non_grouped_annotation_not_in_group_by(self):
|
def test_non_grouped_annotation_not_in_group_by(self):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue