Browse Source

Refs #31720 -- Defined default output_field of BoolAnd() and BoolOr() aggregate functions.

David Chorpash 4 years ago
parent
commit
6ec5eb5d74

+ 3 - 1
django/contrib/postgres/aggregates/general.py

@@ -1,5 +1,5 @@
 from django.contrib.postgres.fields import ArrayField
-from django.db.models import Aggregate, JSONField, Value
+from django.db.models import Aggregate, BooleanField, JSONField, Value
 
 from .mixins import OrderableAggMixin
 
@@ -33,10 +33,12 @@ class BitOr(Aggregate):
 
 class BoolAnd(Aggregate):
     function = 'BOOL_AND'
+    output_field = BooleanField()
 
 
 class BoolOr(Aggregate):
     function = 'BOOL_OR'
+    output_field = BooleanField()
 
 
 class JSONBAgg(OrderableAggMixin, Aggregate):

+ 4 - 4
docs/ref/contrib/postgres/aggregates.txt

@@ -82,11 +82,11 @@ General-purpose aggregation functions
             published = models.BooleanField()
             rank = models.IntegerField()
 
-        >>> from django.db.models import BooleanField, Q
+        >>> from django.db.models import Q
         >>> from django.contrib.postgres.aggregates import BoolAnd
         >>> Comment.objects.aggregate(booland=BoolAnd('published'))
         {'booland': False}
-        >>> Comment.objects.aggregate(booland=BoolAnd(Q(rank__lt=100), output_field=BooleanField()))
+        >>> Comment.objects.aggregate(booland=BoolAnd(Q(rank__lt=100)))
         {'booland': True}
 
 ``BoolOr``
@@ -104,11 +104,11 @@ General-purpose aggregation functions
             published = models.BooleanField()
             rank = models.IntegerField()
 
-        >>> from django.db.models import BooleanField, Q
+        >>> from django.db.models import Q
         >>> from django.contrib.postgres.aggregates import BoolOr
         >>> Comment.objects.aggregate(boolor=BoolOr('published'))
         {'boolor': True}
-        >>> Comment.objects.aggregate(boolor=BoolOr(Q(rank__gt=2), output_field=BooleanField()))
+        >>> Comment.objects.aggregate(boolor=BoolOr(Q(rank__gt=2)))
         {'boolor': False}
 
 ``JSONBAgg``

+ 12 - 0
tests/postgres_tests/test_aggregates.py

@@ -155,6 +155,12 @@ class TestGeneralAggregate(PostgreSQLTestCase):
         values = AggregateTestModel.objects.aggregate(booland=BoolAnd('boolean_field'))
         self.assertEqual(values, {'booland': None})
 
+    def test_bool_and_q_object(self):
+        values = AggregateTestModel.objects.aggregate(
+            booland=BoolAnd(Q(integer_field__gt=2)),
+        )
+        self.assertEqual(values, {'booland': False})
+
     def test_bool_or_general(self):
         values = AggregateTestModel.objects.aggregate(boolor=BoolOr('boolean_field'))
         self.assertEqual(values, {'boolor': True})
@@ -164,6 +170,12 @@ class TestGeneralAggregate(PostgreSQLTestCase):
         values = AggregateTestModel.objects.aggregate(boolor=BoolOr('boolean_field'))
         self.assertEqual(values, {'boolor': None})
 
+    def test_bool_or_q_object(self):
+        values = AggregateTestModel.objects.aggregate(
+            boolor=BoolOr(Q(integer_field__gt=2)),
+        )
+        self.assertEqual(values, {'boolor': False})
+
     def test_string_agg_requires_delimiter(self):
         with self.assertRaises(TypeError):
             AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field'))