Opened 3 weeks ago

Closed 2 weeks ago

#37274 closed Bug (fixed)

Transforms in order_by() not allowed after alias()

Reported by: Jacob Walls Owned by: Jacob Walls
Component: Database layer (models, ORM) Version: 6.1
Severity: Normal Keywords:
Cc: Pravin Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

This example fails with:

django.core.exceptions.FieldError: Cannot resolve keyword 'other_pubdate' into field. Choices are: ... other_pubdate, ...
  • tests/annotations/tests.py

    diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py
    index 42fccca7d6..4baef9e463 100644
    a b class AliasTests(TestCase):  
    14811481        self.assertIs(hasattr(qs.first(), "other_age"), False)
    14821482        self.assertQuerySetEqual(qs, [34, 34, 35, 46, 57], lambda a: a.age)
    14831483
     1484    def test_order_by_alias_transform(self):
     1485        qs = (
     1486            Book.objects.alias(other_pubdate=F("pubdate"))
     1487            .order_by("-other_pubdate__year")
     1488        )
     1489        self.assertQuerySetEqual(qs, [2008, 2007, 1995, 1991], lambda a: a.pubdate.year)
     1490
    14841491    def test_order_by_alias_aggregate(self):
    14851492        qs = (
    14861493            Author.objects.values("age")

However, all of these variants work, suggesting to me that there should be a simple fix.

Keep the transform, change alias to annotate:

Book.objects.annotate(other_pubdate=F("pubdate")).order_by("other_pubdate__year")

Keep the transform, use a field name:

Book.objects.order_by("pubdate__year")

Keep the alias, drop the transform:

Book.objects.alias(other_pubdate=F("pubdate")).order_by("other_pubdate")

If not practical for some reason, then at the very least we should improve "Cannot resolve keyword 'other_pubdate' into field. Choices are: ... other_pubdate, ...".

Change History (10)

comment:1 by Pravin, 3 weeks ago

The simple fix i could see around https://github.com/django/django/blob/c6be0bf3bb744d234947cefd6def9f31d9655800/django/db/models/sql/query.py#L2342
for example,

diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index adf0663beb..91d3436cf0 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -2339,7 +2339,7 @@ class Query(BaseExpression):
                 if item == "?":
                     continue
                 item = item.removeprefix("-")
-                if item in self.annotations:
+                if item in self.annotations or self.annotations.get(item.split(LOOKUP_SEP)[0]):
                     continue
                 if self.extra and item in self.extra:
                     continue

But this may introduce edge around bad aliases , it will failed if there is __ in the alias, as we already discussed similar in Multi-column subquery work

Last edited 3 weeks ago by Pravin (previous) (diff)

comment:2 by Jacob Walls, 3 weeks ago

Has patch: set
Owner: set to Jacob Walls
Status: newassigned

comment:3 by Jacob Walls, 3 weeks ago

Patch needs improvement: set

comment:4 by Jacob Walls, 3 weeks ago

Patch needs improvement: unset

comment:5 by Sarah Boyce, 3 weeks ago

Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

Thank you! The bad error is a regression from dce1b9c2de00a3385c029c02dca325f44e7697a4 (refs #36480)


comment:6 by Jacob Walls, 3 weeks ago

Good point about the recent change. My PR adds support for this use -- do you think we should backport that, or just backport something that improves the error message and defers the feature?

comment:7 by Sarah Boyce, 2 weeks ago

I think this will fall into the "mergers' discretion" category and both choices are fine for me. As you are 6.1's release manager, happy to do whatever option you prefer

comment:8 by Sarah Boyce, 2 weeks ago

Severity: Release blockerNormal

Demoting from release blocker as this never worked "well" prior to dce1b9c2de00a3385c029c02dca325f44e7697a4 and updating the error message to be clearer for 6.1 doesn't feel needed

comment:9 by Sarah Boyce, 2 weeks ago

Triage Stage: AcceptedReady for checkin
Version 0, edited 2 weeks ago by Sarah Boyce (next)

comment:10 by Jacob Walls <jacobtylerwalls@…>, 2 weeks ago

Resolution: fixed
Status: assignedclosed

In be6cf832:

Fixed #37274 -- Allowed transforms in order_by() after alias().

Note: See TracTickets for help on using tickets.
Back to Top