mirror of
https://github.com/django/django.git
synced 2025-06-15 08:29:11 +00:00
Fixed #36407 -- Ensured default value is cast in Case expressions used in ORDER BY clause.
Thanks to deceze for the report. Thanks to Sarah Boyce for the test. Thanks to Simon Charette for the investigation and review.
This commit is contained in:
parent
51923c576a
commit
68c9f7e0b7
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user