Fixed #27767 -- Added distinct argument to ArrayAgg.

This commit is contained in:
orf 2017-01-23 15:34:42 +00:00 committed by Tim Graham
parent 245f209109
commit b5393028bf
5 changed files with 25 additions and 3 deletions

View File

@ -756,6 +756,7 @@ answer newbie questions, and generally made Django that much better:
tobias@neuyork.de
Todd O'Bryan <toddobryan@mac.com>
Tom Christie <tom@tomchristie.com>
Tom Forbes <tom@tomforb.es>
Tom Insam
Tom Tobin
Tomáš Ehrlich <tomas.ehrlich@gmail.com>

View File

@ -8,6 +8,10 @@ __all__ = [
class ArrayAgg(Aggregate):
function = 'ARRAY_AGG'
template = '%(function)s(%(distinct)s%(expressions)s)'
def __init__(self, expression, distinct=False, **extra):
super().__init__(expression, distinct='DISTINCT ' if distinct else '', **extra)
def convert_value(self, value, expression, connection, context):
if not value:

View File

@ -22,10 +22,17 @@ General-purpose aggregation functions
``ArrayAgg``
------------
.. class:: ArrayAgg(expression, **extra)
.. class:: ArrayAgg(expression, distinct=False, **extra)
Returns a list of values, including nulls, concatenated into an array.
.. attribute:: distinct
.. versionadded:: 2.0
An optional boolean argument that determines if array values
will be distinct. Defaults to ``False``.
``BitAnd``
----------

View File

@ -72,7 +72,9 @@ Minor features
:mod:`django.contrib.postgres`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* ...
* The new ``distinct`` argument for
:class:`~django.contrib.postgres.aggregates.ArrayAgg` determines if
concatenated values will be distinct.
:mod:`django.contrib.redirects`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -128,7 +128,7 @@ class TestGeneralAggregate(PostgreSQLTestCase):
self.assertEqual(values, json.loads('{"jsonagg": []}'))
class TestStringAggregateDistinct(PostgreSQLTestCase):
class TestAggregateDistinct(PostgreSQLTestCase):
@classmethod
def setUpTestData(cls):
AggregateTestModel.objects.create(char_field='Foo')
@ -145,6 +145,14 @@ class TestStringAggregateDistinct(PostgreSQLTestCase):
self.assertEqual(values['stringagg'].count('Foo'), 1)
self.assertEqual(values['stringagg'].count('Bar'), 1)
def test_array_agg_distinct_false(self):
values = AggregateTestModel.objects.aggregate(arrayagg=ArrayAgg('char_field', distinct=False))
self.assertEqual(sorted(values['arrayagg']), ['Bar', 'Foo', 'Foo'])
def test_array_agg_distinct_true(self):
values = AggregateTestModel.objects.aggregate(arrayagg=ArrayAgg('char_field', distinct=True))
self.assertEqual(sorted(values['arrayagg']), ['Bar', 'Foo'])
class TestStatisticsAggregate(PostgreSQLTestCase):
@classmethod