From 7d7e5cd0554aab03d3e2732a67a2680d48fa48f7 Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Fri, 5 Sep 2025 14:15:50 -0400 Subject: [PATCH] Refs #35444 -- Removed contrib.postgres aggregates ordering kwarg per deprecation timeline. --- django/contrib/postgres/aggregates/general.py | 14 ++---- django/contrib/postgres/aggregates/mixins.py | 22 +--------- docs/ref/contrib/postgres/aggregates.txt | 15 ------- docs/releases/6.1.txt | 6 +++ tests/postgres_tests/test_aggregates.py | 44 +------------------ 5 files changed, 12 insertions(+), 89 deletions(-) diff --git a/django/contrib/postgres/aggregates/general.py b/django/contrib/postgres/aggregates/general.py index b2ecd18ffb..ad3ff684cb 100644 --- a/django/contrib/postgres/aggregates/general.py +++ b/django/contrib/postgres/aggregates/general.py @@ -6,8 +6,6 @@ from django.db.models import StringAgg as _StringAgg from django.db.models import Value from django.utils.deprecation import RemovedInDjango70Warning -from .mixins import _DeprecatedOrdering - __all__ = [ "ArrayAgg", "BitAnd", @@ -20,9 +18,7 @@ __all__ = [ ] -# RemovedInDjango61Warning: When the deprecation ends, replace with: -# class ArrayAgg(Aggregate): -class ArrayAgg(_DeprecatedOrdering, Aggregate): +class ArrayAgg(Aggregate): function = "ARRAY_AGG" allow_distinct = True allow_order_by = True @@ -54,19 +50,15 @@ class BoolOr(Aggregate): output_field = BooleanField() -# RemovedInDjango61Warning: When the deprecation ends, replace with: -# class JSONBAgg(Aggregate): -class JSONBAgg(_DeprecatedOrdering, Aggregate): +class JSONBAgg(Aggregate): function = "JSONB_AGG" allow_distinct = True allow_order_by = True output_field = JSONField() -# RemovedInDjango61Warning: When the deprecation ends, replace with: -# class StringAgg(_StringAgg): # RemovedInDjango70Warning: When the deprecation ends, remove completely. -class StringAgg(_DeprecatedOrdering, _StringAgg): +class StringAgg(_StringAgg): def __init__(self, expression, delimiter, **extra): if isinstance(delimiter, str): diff --git a/django/contrib/postgres/aggregates/mixins.py b/django/contrib/postgres/aggregates/mixins.py index a6849c3930..5cfe47d96c 100644 --- a/django/contrib/postgres/aggregates/mixins.py +++ b/django/contrib/postgres/aggregates/mixins.py @@ -1,29 +1,11 @@ # RemovedInDjango70Warning: When the deprecation ends, remove completely. import warnings -from django.utils.deprecation import RemovedInDjango61Warning, RemovedInDjango70Warning - - -# RemovedInDjango61Warning. -class _DeprecatedOrdering: - def __init__(self, *expressions, ordering=(), order_by=(), **extra): - if ordering: - warnings.warn( - "The ordering argument is deprecated. Use order_by instead.", - category=RemovedInDjango61Warning, - stacklevel=2, - ) - if order_by: - raise TypeError("Cannot specify both order_by and ordering.") - order_by = ordering - - super().__init__(*expressions, order_by=order_by, **extra) +from django.utils.deprecation import RemovedInDjango70Warning # RemovedInDjango70Warning. -# RemovedInDjango61Warning: When the deprecation ends, replace with: -# class OrderableAggMixin: -class OrderableAggMixin(_DeprecatedOrdering): +class OrderableAggMixin: allow_order_by = True def __init_subclass__(cls, /, *args, **kwargs): diff --git a/docs/ref/contrib/postgres/aggregates.txt b/docs/ref/contrib/postgres/aggregates.txt index 81e54547e5..d2bd48c4fd 100644 --- a/docs/ref/contrib/postgres/aggregates.txt +++ b/docs/ref/contrib/postgres/aggregates.txt @@ -54,11 +54,6 @@ General-purpose aggregation functions ArrayAgg("a_field", order_by="-some_field") ArrayAgg("a_field", order_by=F("some_field").desc()) - .. deprecated:: 5.2 - - The ``ordering`` keyword argument is deprecated. Use - :attr:`ArrayAgg.order_by` instead. - ``BitAnd`` ---------- @@ -180,11 +175,6 @@ General-purpose aggregation functions {'parking': True, 'double_bed': True} ]}]> - .. deprecated:: 5.2 - - The ``ordering`` keyword argument is deprecated. Use - :attr:`JSONBAgg.order_by` instead. - ``StringAgg`` ------------- @@ -242,11 +232,6 @@ General-purpose aggregation functions 'headline': 'NASA uses Python', 'publication_names': 'Science News, The Python Journal' }]> - .. deprecated:: 5.2 - - The ``ordering`` keyword argument is deprecated. Use - :attr:`StringAgg.order_by` instead. - Aggregate functions for statistics ================================== diff --git a/docs/releases/6.1.txt b/docs/releases/6.1.txt index c95b9b1c57..5b98cda2a6 100644 --- a/docs/releases/6.1.txt +++ b/docs/releases/6.1.txt @@ -272,3 +272,9 @@ to remove usage of these features. * Fallbacks to ``request.user`` and ``request.auser()`` when ``user`` is ``None`` in ``django.contrib.auth.login()`` and ``django.contrib.auth.alogin()``, respectively, are removed. + +* The ``ordering`` keyword parameter of the PostgreSQL specific aggregation + functions ``django.contrib.postgres.aggregates.ArrayAgg``, + ``django.contrib.postgres.aggregates.JSONBAgg``, and + ``django.contrib.postgres.aggregates.StringAgg`` are removed in favor + of the ``order_by`` parameter. diff --git a/tests/postgres_tests/test_aggregates.py b/tests/postgres_tests/test_aggregates.py index 621fa43d91..e3a5521f74 100644 --- a/tests/postgres_tests/test_aggregates.py +++ b/tests/postgres_tests/test_aggregates.py @@ -1,5 +1,3 @@ -import warnings - from django.db import transaction from django.db.models import ( CharField, @@ -17,7 +15,7 @@ from django.db.models.fields.json import KeyTransform from django.db.models.functions import Cast, Concat, LPad, Substr from django.test.utils import Approximate from django.utils import timezone -from django.utils.deprecation import RemovedInDjango61Warning, RemovedInDjango70Warning +from django.utils.deprecation import RemovedInDjango70Warning from . import PostgreSQLTestCase from .models import AggregateTestModel, HotelReservation, Room, StatTestModel @@ -147,46 +145,6 @@ class TestGeneralAggregate(PostgreSQLTestCase): ) self.assertEqual(values, {"aggregation": expected_result}) - def test_ordering_warns_of_deprecation(self): - msg = "The ordering argument is deprecated. Use order_by instead." - with self.assertWarnsMessage(RemovedInDjango61Warning, msg) as ctx: - values = AggregateTestModel.objects.aggregate( - arrayagg=ArrayAgg("integer_field", ordering=F("integer_field").desc()) - ) - self.assertEqual(values, {"arrayagg": [2, 1, 0, 0]}) - self.assertEqual(ctx.filename, __file__) - - # RemovedInDjango61Warning: Remove this test - def test_ordering_and_order_by_causes_error(self): - with warnings.catch_warnings(record=True, action="always") as wm: - with self.assertRaisesMessage( - TypeError, - "Cannot specify both order_by and ordering.", - ): - AggregateTestModel.objects.aggregate( - stringagg=StringAgg( - "char_field", - delimiter=Value("'"), - order_by="char_field", - ordering="char_field", - ) - ) - - first_warning = wm[0] - self.assertEqual(first_warning.category, RemovedInDjango70Warning) - self.assertEqual( - "The PostgreSQL specific StringAgg function is deprecated. Use " - "django.db.models.aggregate.StringAgg instead.", - str(first_warning.message), - ) - - second_warning = wm[1] - self.assertEqual(second_warning.category, RemovedInDjango61Warning) - self.assertEqual( - "The ordering argument is deprecated. Use order_by instead.", - str(second_warning.message), - ) - def test_array_agg_charfield(self): values = AggregateTestModel.objects.aggregate(arrayagg=ArrayAgg("char_field")) self.assertEqual(values, {"arrayagg": ["Foo1", "Foo2", "Foo4", "Foo3"]})