diff options
| author | orf <tom@tomforb.es> | 2017-01-23 15:34:42 +0000 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-02-04 13:57:39 -0500 |
| commit | b5393028bfc939adf14d0fa5e4088cddd3b9dfa1 (patch) | |
| tree | 4168b42b77be5bce7d3b8d0acf2819098344412c | |
| parent | 245f20910906c8f17e1011a00f7042e1d8f39c76 (diff) | |
Fixed #27767 -- Added distinct argument to ArrayAgg.
| -rw-r--r-- | AUTHORS | 1 | ||||
| -rw-r--r-- | django/contrib/postgres/aggregates/general.py | 4 | ||||
| -rw-r--r-- | docs/ref/contrib/postgres/aggregates.txt | 9 | ||||
| -rw-r--r-- | docs/releases/2.0.txt | 4 | ||||
| -rw-r--r-- | tests/postgres_tests/test_aggregates.py | 10 |
5 files changed, 25 insertions, 3 deletions
@@ -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> diff --git a/django/contrib/postgres/aggregates/general.py b/django/contrib/postgres/aggregates/general.py index ac18a516d6..91835a9ca3 100644 --- a/django/contrib/postgres/aggregates/general.py +++ b/django/contrib/postgres/aggregates/general.py @@ -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: diff --git a/docs/ref/contrib/postgres/aggregates.txt b/docs/ref/contrib/postgres/aggregates.txt index 3939023e26..1c738c35ae 100644 --- a/docs/ref/contrib/postgres/aggregates.txt +++ b/docs/ref/contrib/postgres/aggregates.txt @@ -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`` ---------- diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 4e42bd2b55..a43ae5e368 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -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` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/postgres_tests/test_aggregates.py b/tests/postgres_tests/test_aggregates.py index 9aa0e06595..056d08441b 100644 --- a/tests/postgres_tests/test_aggregates.py +++ b/tests/postgres_tests/test_aggregates.py @@ -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 |
