From 94ad46e9d8077d8fadce991af85be657b4a4e2a0 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Fri, 13 Jan 2023 09:49:28 +0100 Subject: [PATCH] Refs #33543 -- Made Expression.asc()/desc() and OrderBy raise ValueError when nulls_first/nulls_last=False is passed. Per deprecation timeline. --- django/db/models/expressions.py | 13 +------------ docs/ref/models/expressions.txt | 10 ---------- docs/releases/5.0.txt | 4 ++++ tests/expressions/tests.py | 17 +++++------------ 4 files changed, 10 insertions(+), 34 deletions(-) diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index c270ef16c7..5a1838809c 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -2,7 +2,6 @@ import copy import datetime import functools import inspect -import warnings from collections import defaultdict from decimal import Decimal from uuid import UUID @@ -13,7 +12,6 @@ from django.db.models import fields from django.db.models.constants import LOOKUP_SEP from django.db.models.query_utils import Q from django.utils.deconstruct import deconstructible -from django.utils.deprecation import RemovedInDjango50Warning from django.utils.functional import cached_property from django.utils.hashable import make_hashable @@ -1571,16 +1569,7 @@ class OrderBy(Expression): if nulls_first and nulls_last: raise ValueError("nulls_first and nulls_last are mutually exclusive") if nulls_first is False or nulls_last is False: - # When the deprecation ends, replace with: - # raise ValueError( - # "nulls_first and nulls_last values must be True or None." - # ) - warnings.warn( - "Passing nulls_first=False or nulls_last=False is deprecated, use None " - "instead.", - RemovedInDjango50Warning, - stacklevel=2, - ) + raise ValueError("nulls_first and nulls_last values must be True or None.") self.nulls_first = nulls_first self.nulls_last = nulls_last self.descending = descending diff --git a/docs/ref/models/expressions.txt b/docs/ref/models/expressions.txt index 93a4bf32ab..214010f139 100644 --- a/docs/ref/models/expressions.txt +++ b/docs/ref/models/expressions.txt @@ -1063,11 +1063,6 @@ calling the appropriate methods on the wrapped expression. ``nulls_first`` and ``nulls_last`` define how null values are sorted. See :ref:`using-f-to-sort-null-values` for example usage. - .. deprecated:: 4.1 - - Passing ``nulls_first=False`` or ``nulls_last=False`` to ``asc()`` - is deprecated. Use ``None`` instead. - .. method:: desc(nulls_first=None, nulls_last=None) Returns the expression ready to be sorted in descending order. @@ -1075,11 +1070,6 @@ calling the appropriate methods on the wrapped expression. ``nulls_first`` and ``nulls_last`` define how null values are sorted. See :ref:`using-f-to-sort-null-values` for example usage. - .. deprecated:: 4.1 - - Passing ``nulls_first=False`` or ``nulls_last=False`` to ``desc()`` - is deprecated. Use ``None`` instead. - .. method:: reverse_ordering() Returns ``self`` with any modifications required to reverse the sort diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt index d8212e69e6..494b20200c 100644 --- a/docs/releases/5.0.txt +++ b/docs/releases/5.0.txt @@ -347,3 +347,7 @@ to remove usage of these features. ``"django/forms/formsets/default.html"`` templates are removed. * The default form and formset rendering style is changed to the div-based. + +* Passing ``nulls_first=False`` or ``nulls_last=False`` to ``Expression.asc()`` + and ``Expression.desc()`` methods, and the ``OrderBy`` expression is no + longer allowed. diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 7db6013819..8a3b5d45f5 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -70,7 +70,6 @@ from django.test.utils import ( isolate_apps, register_lookup, ) -from django.utils.deprecation import RemovedInDjango50Warning from django.utils.functional import SimpleLazyObject from .models import ( @@ -2632,18 +2631,12 @@ class OrderByTests(SimpleTestCase): ) def test_nulls_false(self): - # These tests will catch ValueError in Django 5.0 when passing False to - # nulls_first and nulls_last becomes forbidden. - # msg = "nulls_first and nulls_last values must be True or None." - msg = ( - "Passing nulls_first=False or nulls_last=False is deprecated, use None " - "instead." - ) - with self.assertRaisesMessage(RemovedInDjango50Warning, msg): + msg = "nulls_first and nulls_last values must be True or None." + with self.assertRaisesMessage(ValueError, msg): OrderBy(F("field"), nulls_first=False) - with self.assertRaisesMessage(RemovedInDjango50Warning, msg): + with self.assertRaisesMessage(ValueError, msg): OrderBy(F("field"), nulls_last=False) - with self.assertRaisesMessage(RemovedInDjango50Warning, msg): + with self.assertRaisesMessage(ValueError, msg): F("field").asc(nulls_first=False) - with self.assertRaisesMessage(RemovedInDjango50Warning, msg): + with self.assertRaisesMessage(ValueError, msg): F("field").desc(nulls_last=False)