Skip to content

Commit 8adc7c8

Browse files
lufafajoshuanessita
authored andcommitted
Fixed #34808 -- Doc'd aggregate function's default argument.
1 parent fc62e17 commit 8adc7c8

File tree

2 files changed

+55
-10
lines changed

2 files changed

+55
-10
lines changed

docs/ref/models/querysets.txt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3909,7 +3909,8 @@ by the aggregate.
39093909

39103910
* Default alias: ``<field>__avg``
39113911
* Return type: ``float`` if input is ``int``, otherwise same as input
3912-
field, or ``output_field`` if supplied
3912+
field, or ``output_field`` if supplied. If the queryset or grouping is
3913+
empty, ``default`` is returned.
39133914

39143915
.. attribute:: distinct
39153916

@@ -3947,7 +3948,8 @@ by the aggregate.
39473948
Returns the maximum value of the given expression.
39483949

39493950
* Default alias: ``<field>__max``
3950-
* Return type: same as input field, or ``output_field`` if supplied
3951+
* Return type: same as input field, or ``output_field`` if supplied. If the
3952+
queryset or grouping is empty, ``default`` is returned.
39513953

39523954
``Min``
39533955
~~~~~~~
@@ -3957,7 +3959,8 @@ by the aggregate.
39573959
Returns the minimum value of the given expression.
39583960

39593961
* Default alias: ``<field>__min``
3960-
* Return type: same as input field, or ``output_field`` if supplied
3962+
* Return type: same as input field, or ``output_field`` if supplied. If the
3963+
queryset or grouping is empty, ``default`` is returned.
39613964

39623965
``StdDev``
39633966
~~~~~~~~~~
@@ -3968,7 +3971,8 @@ by the aggregate.
39683971

39693972
* Default alias: ``<field>__stddev``
39703973
* Return type: ``float`` if input is ``int``, otherwise same as input
3971-
field, or ``output_field`` if supplied
3974+
field, or ``output_field`` if supplied. If the queryset or grouping is
3975+
empty, ``default`` is returned.
39723976

39733977
.. attribute:: sample
39743978

@@ -3984,7 +3988,8 @@ by the aggregate.
39843988
Computes the sum of all values of the given expression.
39853989

39863990
* Default alias: ``<field>__sum``
3987-
* Return type: same as input field, or ``output_field`` if supplied
3991+
* Return type: same as input field, or ``output_field`` if supplied. If the
3992+
queryset or grouping is empty, ``default`` is returned.
39883993

39893994
.. attribute:: distinct
39903995

@@ -4001,7 +4006,8 @@ by the aggregate.
40014006

40024007
* Default alias: ``<field>__variance``
40034008
* Return type: ``float`` if input is ``int``, otherwise same as input
4004-
field, or ``output_field`` if supplied
4009+
field, or ``output_field`` if supplied. If the queryset or grouping is
4010+
empty, ``default`` is returned.
40054011

40064012
.. attribute:: sample
40074013

docs/topics/db/aggregation.txt

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,16 @@ above:
6060
>>> Book.objects.filter(publisher__name="BaloneyPress").count()
6161
73
6262

63-
# Average price across all books.
63+
# Average price across all books, provide default to be returned instead
64+
# of None if no books exist.
6465
>>> from django.db.models import Avg
65-
>>> Book.objects.aggregate(Avg("price"))
66+
>>> Book.objects.aggregate(Avg("price", default=0))
6667
{'price__avg': 34.35}
6768

68-
# Max price across all books.
69+
# Max price across all books, provide default to be returned instead of
70+
# None if no books exist.
6971
>>> from django.db.models import Max
70-
>>> Book.objects.aggregate(Max("price"))
72+
>>> Book.objects.aggregate(Max("price", default=0))
7173
{'price__max': Decimal('81.20')}
7274

7375
# Difference between the highest priced book and the average price of all books.
@@ -632,3 +634,40 @@ aggregate that author count, referencing the annotation field:
632634
>>> from django.db.models import Avg, Count
633635
>>> Book.objects.annotate(num_authors=Count("authors")).aggregate(Avg("num_authors"))
634636
{'num_authors__avg': 1.66}
637+
638+
Aggregating on empty querysets or groups
639+
----------------------------------------
640+
641+
When an aggregation is applied to an empty queryset or grouping, the result
642+
defaults to its :ref:`default <aggregate-default>` parameter, typically
643+
``None``. This behavior occurs because aggregate functions return ``NULL`` when
644+
the executed query returns no rows.
645+
646+
You can specify a return value by providing the :ref:`default
647+
<aggregate-default>` argument for most aggregations. However, since
648+
:class:`~django.db.models.Count` does not support the :ref:`default
649+
<aggregate-default>` argument, it will always return ``0`` for empty querysets
650+
or groups.
651+
652+
For example, assuming that no book contains *web* in its name, calculating the
653+
total price for this book set would return ``None`` since there are no matching
654+
rows to compute the :class:`~django.db.models.Sum` aggregation on:
655+
656+
.. code-block:: pycon
657+
658+
>>> from django.db.models import Sum
659+
>>> Book.objects.filter(name__contains="web").aggregate(Sum("price"))
660+
{"price__sum": None}
661+
662+
However, the :ref:`default <aggregate-default>` argument can be set when
663+
calling :class:`~django.db.models.Sum` to return a different default value if
664+
no books can be found:
665+
666+
.. code-block:: pycon
667+
668+
>>> Book.objects.filter(name__contains="web").aggregate(Sum("price", default=0))
669+
{"price__sum": Decimal("0")}
670+
671+
Under the hood, the :ref:`default <aggregate-default>` argument is implemented
672+
by wrapping the aggregate function with
673+
:class:`~django.db.models.functions.Coalesce`.

0 commit comments

Comments
 (0)