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

This commit is contained in:
David Chorpash 2020-07-19 02:08:44 -06:00 committed by Mariusz Felisiak
parent a2e621b14e
commit 6ec5eb5d74
3 changed files with 19 additions and 5 deletions

View File

@ -1,5 +1,5 @@
from django.contrib.postgres.fields import ArrayField 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 from .mixins import OrderableAggMixin
@ -33,10 +33,12 @@ class BitOr(Aggregate):
class BoolAnd(Aggregate): class BoolAnd(Aggregate):
function = 'BOOL_AND' function = 'BOOL_AND'
output_field = BooleanField()
class BoolOr(Aggregate): class BoolOr(Aggregate):
function = 'BOOL_OR' function = 'BOOL_OR'
output_field = BooleanField()
class JSONBAgg(OrderableAggMixin, Aggregate): class JSONBAgg(OrderableAggMixin, Aggregate):

View File

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

View File

@ -155,6 +155,12 @@ class TestGeneralAggregate(PostgreSQLTestCase):
values = AggregateTestModel.objects.aggregate(booland=BoolAnd('boolean_field')) values = AggregateTestModel.objects.aggregate(booland=BoolAnd('boolean_field'))
self.assertEqual(values, {'booland': None}) 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): def test_bool_or_general(self):
values = AggregateTestModel.objects.aggregate(boolor=BoolOr('boolean_field')) values = AggregateTestModel.objects.aggregate(boolor=BoolOr('boolean_field'))
self.assertEqual(values, {'boolor': True}) self.assertEqual(values, {'boolor': True})
@ -164,6 +170,12 @@ class TestGeneralAggregate(PostgreSQLTestCase):
values = AggregateTestModel.objects.aggregate(boolor=BoolOr('boolean_field')) values = AggregateTestModel.objects.aggregate(boolor=BoolOr('boolean_field'))
self.assertEqual(values, {'boolor': None}) 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): def test_string_agg_requires_delimiter(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field')) AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field'))