diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 46c3b63a91..54e372ea01 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -1711,14 +1711,24 @@ class Case(SQLiteNumericMixin, Expression): except EmptyResultSet: continue except FullResultSet: - default_sql, default_params = compiler.compile(case.result) + default = case.result break case_parts.append(case_sql) sql_params.extend(case_params) else: - default_sql, default_params = compiler.compile(self.default) - if not case_parts: - return default_sql, default_params + default = self.default + if case_parts: + default_sql, default_params = compiler.compile(default) + else: + if ( + isinstance(default, Value) + and (output_field := default._output_field_or_none) is not None + ): + from django.db.models.functions import Cast + + default = Cast(default, output_field) + return compiler.compile(default) + case_joiner = case_joiner or self.case_joiner template_params["cases"] = case_joiner.join(case_parts) template_params["default"] = default_sql diff --git a/tests/ordering/tests.py b/tests/ordering/tests.py index b29404ed77..421689b9fa 100644 --- a/tests/ordering/tests.py +++ b/tests/ordering/tests.py @@ -3,15 +3,18 @@ from operator import attrgetter from django.core.exceptions import FieldError from django.db.models import ( + Case, CharField, Count, DateTimeField, F, + IntegerField, Max, OrderBy, OuterRef, Subquery, Value, + When, ) from django.db.models.functions import Length, Upper from django.test import TestCase @@ -526,6 +529,17 @@ class OrderingTests(TestCase): qs = Article.objects.order_by(Value("1", output_field=CharField()), "-headline") self.assertSequenceEqual(qs, [self.a4, self.a3, self.a2, self.a1]) + def test_order_by_case_when_constant_value(self): + qs = Article.objects.order_by( + Case( + When(pk__in=[], then=Value(1)), + default=Value(0), + output_field=IntegerField(), + ).desc(), + "pk", + ) + self.assertSequenceEqual(qs, [self.a1, self.a2, self.a3, self.a4]) + def test_related_ordering_duplicate_table_reference(self): """ An ordering referencing a model with an ordering referencing a model