Fixed #34012 -- Made QuerySet.order_by() apply transforms on related fields for models with Meta.ordering.
This makes QuerySet.order_by() no longer ignore trailing transforms for models with Meta.ordering. As a consequence, FieldError is raised in such cases for non-existent fields. Thanks to Klaas van Schelven for the report and Mariusz Felisiak for the review and advice.
This commit is contained in:
parent
649b28eab6
commit
4771a1694b
|
@ -1001,12 +1001,14 @@ class SQLCompiler:
|
|||
|
||||
# If we get to this point and the field is a relation to another model,
|
||||
# append the default ordering for that model unless it is the pk
|
||||
# shortcut or the attribute name of the field that is specified.
|
||||
# shortcut or the attribute name of the field that is specified or
|
||||
# there are transforms to process.
|
||||
if (
|
||||
field.is_relation
|
||||
and opts.ordering
|
||||
and getattr(field, "attname", None) != pieces[-1]
|
||||
and name != "pk"
|
||||
and not getattr(transform_function, "has_transforms", False)
|
||||
):
|
||||
# Firstly, avoid infinite loops.
|
||||
already_seen = already_seen or set()
|
||||
|
|
|
@ -1819,6 +1819,7 @@ class Query(BaseExpression):
|
|||
final_transformer = functools.partial(
|
||||
transform, name=name, previous=final_transformer
|
||||
)
|
||||
final_transformer.has_transforms = True
|
||||
# Then, add the path to the query's joins. Note that we can't trim
|
||||
# joins at this stage - we will need the information about join type
|
||||
# of the trimmed joins.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from datetime import datetime
|
||||
from operator import attrgetter
|
||||
|
||||
from django.core.exceptions import FieldError
|
||||
from django.db.models import (
|
||||
CharField,
|
||||
Count,
|
||||
|
@ -91,6 +92,18 @@ class OrderingTests(TestCase):
|
|||
attrgetter("headline"),
|
||||
)
|
||||
|
||||
def test_default_ordering_override_unknown_field(self):
|
||||
"""
|
||||
Attempts to override default ordering on related models with an unknown
|
||||
field should result in an error.
|
||||
"""
|
||||
msg = (
|
||||
"Cannot resolve keyword 'unknown_field' into field. Choices are: "
|
||||
"article, author, editor, editor_id, id, name"
|
||||
)
|
||||
with self.assertRaisesMessage(FieldError, msg):
|
||||
list(Article.objects.order_by("author__unknown_field"))
|
||||
|
||||
def test_order_by_override(self):
|
||||
"""
|
||||
Only the last order_by has any effect (since they each override any
|
||||
|
|
|
@ -68,6 +68,9 @@ class Annotation(models.Model):
|
|||
class DateTimePK(models.Model):
|
||||
date = models.DateTimeField(primary_key=True, default=datetime.datetime.now)
|
||||
|
||||
class Meta:
|
||||
ordering = ["date"]
|
||||
|
||||
|
||||
class ExtraInfo(models.Model):
|
||||
info = models.CharField(max_length=100)
|
||||
|
|
Loading…
Reference in New Issue