summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnže Pečar <anze@pecar.me>2026-04-18 14:54:55 +0300
committerJacob Walls <jacobtylerwalls@gmail.com>2026-04-19 11:03:11 +0300
commita284a49153f005f2a7af087025e5112ba06cbd5f (patch)
tree1adcc51fd24f588858cf28d6532bdda241214768
parentd33364c7ba330a349e38449c98494323a4ed7c8d (diff)
Fixed #37047 -- Fixed crash in Query.orderby_issubset_groupby for descending and random order_by strings.
Run this example: ```python User.objects.values("is_staff").annotate(latest=Max("date_joined")).order_by("-latest").count() ``` You should see the following exception: ``` django.core.exceptions.FieldError: Cannot resolve keyword '-latest' into field. ``` Regression in 2ce5cb0f7a4618dfdc5f5c10e53e2e9b9543d298.
-rw-r--r--django/db/models/sql/query.py17
-rw-r--r--tests/aggregation_regress/tests.py8
2 files changed, 17 insertions, 8 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 8be560856b..45192b7809 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -2376,14 +2376,15 @@ class Query(BaseExpression):
return True
# Don't pollute the original query (might disrupt joins).
q = self.clone()
- order_by_set = {
- (
- order_by.resolve_expression(q)
- if hasattr(order_by, "resolve_expression")
- else F(order_by).resolve_expression(q)
- )
- for order_by in q.order_by
- }
+ order_by_set = set()
+ for order_by in q.order_by:
+ if hasattr(order_by, "resolve_expression"):
+ order_by_set.add(order_by.resolve_expression(q))
+ elif order_by == "?":
+ # Random ordering can't be compared against group by.
+ return False
+ else:
+ order_by_set.add(F(order_by.removeprefix("-")).resolve_expression(q))
return order_by_set.issubset(self.group_by)
def clear_ordering(self, force=False, clear_default=True):
diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py
index 33763d589b..f2ed13420f 100644
--- a/tests/aggregation_regress/tests.py
+++ b/tests/aggregation_regress/tests.py
@@ -188,6 +188,14 @@ class AggregationTests(TestCase):
)
self.assertEqual(qs.order_by("id").count(), len(qs.order_by("id")))
self.assertEqual(qs.extra(order_by=["id"]).count(), len(qs.order_by("id")))
+ self.assertEqual(qs.order_by("-id").count(), len(qs.order_by("-id")))
+ self.assertEqual(
+ qs.order_by("-publications").count(), len(qs.order_by("-publications"))
+ )
+ self.assertEqual(
+ qs.order_by("-contact__name").count(), len(qs.order_by("-contact__name"))
+ )
+ self.assertEqual(qs.order_by("?").count(), len(qs.order_by("?")))
def test_annotation_with_value(self):
values = (