diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index b524e8859f..3b2211b3b3 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -10,7 +10,6 @@ import copy import difflib import functools import sys -import warnings from collections import Counter, namedtuple from collections.abc import Iterator, Mapping from itertools import chain, count, product @@ -36,7 +35,6 @@ from django.db.models.sql.datastructures import ( from django.db.models.sql.where import ( AND, OR, ExtraWhere, NothingNode, WhereNode, ) -from django.utils.deprecation import RemovedInDjango40Warning from django.utils.functional import cached_property from django.utils.hashable import make_hashable from django.utils.tree import Node @@ -1968,15 +1966,6 @@ class Query(BaseExpression): errors = [] for item in ordering: if isinstance(item, str): - if '.' in item: - warnings.warn( - 'Passing column raw column aliases to order_by() is ' - 'deprecated. Wrap %r in a RawSQL expression before ' - 'passing it to order_by().' % item, - category=RemovedInDjango40Warning, - stacklevel=3, - ) - continue if item == '?': continue if item.startswith('-'): diff --git a/docs/releases/4.0.txt b/docs/releases/4.0.txt index d2e18ee078..d3bb700aac 100644 --- a/docs/releases/4.0.txt +++ b/docs/releases/4.0.txt @@ -303,3 +303,5 @@ to remove usage of these features. * The ``providing_args`` argument for ``django.dispatch.Signal`` is removed. * The ``list`` message for ``ModelMultipleChoiceField`` is removed. + +* Support for passing raw column aliases to ``QuerySet.order_by()`` is removed. diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 37ba239419..1cbe005fa8 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -12,8 +12,7 @@ from django.db.models.expressions import RawSQL from django.db.models.sql.constants import LOUTER from django.db.models.sql.where import NothingNode, WhereNode from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature -from django.test.utils import CaptureQueriesContext, ignore_warnings -from django.utils.deprecation import RemovedInDjango40Warning +from django.test.utils import CaptureQueriesContext from .models import ( FK1, Annotation, Article, Author, BaseA, Book, CategoryItem, @@ -594,13 +593,6 @@ class Queries1Tests(TestCase): [datetime.datetime(2007, 12, 19, 0, 0)], ) - @ignore_warnings(category=RemovedInDjango40Warning) - def test_ticket7098(self): - self.assertSequenceEqual( - Item.objects.values('note__note').order_by('queries_note.note', 'id'), - [{'note__note': 'n2'}, {'note__note': 'n3'}, {'note__note': 'n3'}, {'note__note': 'n3'}] - ) - def test_order_by_rawsql(self): self.assertSequenceEqual( Item.objects.values('note__note').order_by( @@ -615,15 +607,6 @@ class Queries1Tests(TestCase): ], ) - def test_order_by_raw_column_alias_warning(self): - msg = ( - "Passing column raw column aliases to order_by() is deprecated. " - "Wrap 'queries_author.name' in a RawSQL expression before " - "passing it to order_by()." - ) - with self.assertRaisesMessage(RemovedInDjango40Warning, msg): - Item.objects.values('creator__name').order_by('queries_author.name') - def test_ticket7096(self): # Make sure exclude() with multiple conditions continues to work. self.assertSequenceEqual( @@ -3083,6 +3066,15 @@ class QuerySetExceptionTests(SimpleTestCase): with self.assertRaisesMessage(FieldError, msg): Article.objects.order_by('*') + def test_invalid_order_by_raw_column_alias(self): + msg = ( + "Cannot resolve keyword 'queries_author.name' into field. Choices " + "are: cover, created, creator, creator_id, id, modified, name, " + "note, note_id, tags" + ) + with self.assertRaisesMessage(FieldError, msg): + Item.objects.values('creator__name').order_by('queries_author.name') + def test_invalid_queryset_model(self): msg = 'Cannot use QuerySet for "Article": Use a QuerySet for "ExtraInfo".' with self.assertRaisesMessage(ValueError, msg):