Opened 66 minutes ago
Last modified 45 minutes ago
#37274 new Bug
Transforms in order_by() not allowed after alias()
| Reported by: | Jacob Walls | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 6.1 |
| Severity: | Normal | Keywords: | |
| Cc: | Pravin | Triage Stage: | Unreviewed |
| Has patch: | no | 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): 1481 1481 self.assertIs(hasattr(qs.first(), "other_age"), False) 1482 1482 self.assertQuerySetEqual(qs, [34, 34, 35, 46, 57], lambda a: a.age) 1483 1483 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 1484 1491 def test_order_by_alias_aggregate(self): 1485 1492 qs = ( 1486 1493 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, ...".
Note:
See TracTickets
for help on using tickets.
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: continueBut this may introduce edge around bad aliases , it will failed if there is
__in the alias, as we have already discussed similar in Multi-column subquery work