瀏覽代碼

Fixed #34808 -- Doc'd aggregate function's default argument.

lufafajoshua 1 年之前
父節點
當前提交
8adc7c86ab
共有 2 個文件被更改,包括 55 次插入10 次删除
  1. 12 6
      docs/ref/models/querysets.txt
  2. 43 4
      docs/topics/db/aggregation.txt

+ 12 - 6
docs/ref/models/querysets.txt

@@ -3909,7 +3909,8 @@ by the aggregate.
 
     * Default alias: ``<field>__avg``
     * Return type: ``float`` if input is ``int``, otherwise same as input
-      field, or ``output_field`` if supplied
+      field, or ``output_field`` if supplied. If the queryset or grouping is
+      empty, ``default`` is returned.
 
     .. attribute:: distinct
 
@@ -3947,7 +3948,8 @@ by the aggregate.
     Returns the maximum value of the given expression.
 
     * Default alias: ``<field>__max``
-    * Return type: same as input field, or ``output_field`` if supplied
+    * Return type: same as input field, or ``output_field`` if supplied. If the
+      queryset or grouping is empty, ``default`` is returned.
 
 ``Min``
 ~~~~~~~
@@ -3957,7 +3959,8 @@ by the aggregate.
     Returns the minimum value of the given expression.
 
     * Default alias: ``<field>__min``
-    * Return type: same as input field, or ``output_field`` if supplied
+    * Return type: same as input field, or ``output_field`` if supplied. If the
+      queryset or grouping is empty, ``default`` is returned.
 
 ``StdDev``
 ~~~~~~~~~~
@@ -3968,7 +3971,8 @@ by the aggregate.
 
     * Default alias: ``<field>__stddev``
     * Return type: ``float`` if input is ``int``, otherwise same as input
-      field, or ``output_field`` if supplied
+      field, or ``output_field`` if supplied. If the queryset or grouping is
+      empty, ``default`` is returned.
 
     .. attribute:: sample
 
@@ -3984,7 +3988,8 @@ by the aggregate.
     Computes the sum of all values of the given expression.
 
     * 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. If the
+      queryset or grouping is empty, ``default`` is returned.
 
     .. attribute:: distinct
 
@@ -4001,7 +4006,8 @@ by the aggregate.
 
     * Default alias: ``<field>__variance``
     * Return type: ``float`` if input is ``int``, otherwise same as input
-      field, or ``output_field`` if supplied
+      field, or ``output_field`` if supplied. If the queryset or grouping is
+      empty, ``default`` is returned.
 
     .. attribute:: sample
 

+ 43 - 4
docs/topics/db/aggregation.txt

@@ -60,14 +60,16 @@ above:
     >>> Book.objects.filter(publisher__name="BaloneyPress").count()
     73
 
-    # Average price across all books.
+    # Average price across all books, provide default to be returned instead
+    # of None if no books exist.
     >>> from django.db.models import Avg
-    >>> Book.objects.aggregate(Avg("price"))
+    >>> Book.objects.aggregate(Avg("price", default=0))
     {'price__avg': 34.35}
 
-    # Max price across all books.
+    # Max price across all books, provide default to be returned instead of
+    # None if no books exist.
     >>> from django.db.models import Max
-    >>> Book.objects.aggregate(Max("price"))
+    >>> Book.objects.aggregate(Max("price", default=0))
     {'price__max': Decimal('81.20')}
 
     # 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:
     >>> from django.db.models import Avg, Count
     >>> Book.objects.annotate(num_authors=Count("authors")).aggregate(Avg("num_authors"))
     {'num_authors__avg': 1.66}
+
+Aggregating on empty querysets or groups
+----------------------------------------
+
+When an aggregation is applied to an empty queryset or grouping, the result
+defaults to its :ref:`default <aggregate-default>` parameter, typically
+``None``. This behavior occurs because aggregate functions return ``NULL`` when
+the executed query returns no rows.
+
+You can specify a return value by providing the :ref:`default
+<aggregate-default>` argument for most aggregations. However, since
+:class:`~django.db.models.Count` does not support the :ref:`default
+<aggregate-default>` argument, it will always return ``0`` for empty querysets
+or groups.
+
+For example, assuming that no book contains *web* in its name, calculating the
+total price for this book set would return ``None`` since there are no matching
+rows to compute the :class:`~django.db.models.Sum` aggregation on:
+
+.. code-block:: pycon
+
+    >>> from django.db.models import Sum
+    >>> Book.objects.filter(name__contains="web").aggregate(Sum("price"))
+    {"price__sum": None}
+
+However, the :ref:`default <aggregate-default>` argument can be set when
+calling :class:`~django.db.models.Sum` to return a different default value if
+no books can be found:
+
+.. code-block:: pycon
+
+    >>> Book.objects.filter(name__contains="web").aggregate(Sum("price", default=0))
+    {"price__sum": Decimal("0")}
+
+Under the hood, the :ref:`default <aggregate-default>` argument is implemented
+by wrapping the aggregate function with
+:class:`~django.db.models.functions.Coalesce`.