diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 822968ef56..ba836024e5 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -1299,6 +1299,11 @@ class When(Expression): template_params = extra_context sql_params = [] condition_sql, condition_params = compiler.compile(self.condition) + # Filters that match everything are handled as empty strings in the + # WHERE clause, but in a CASE WHEN expression they must use a predicate + # that's always True. + if condition_sql == "": + condition_sql, condition_params = compiler.compile(Value(True)) template_params["condition"] = condition_sql sql_params.extend(condition_params) result_sql, result_params = compiler.compile(self.result) diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py index 9bad0b8747..221806c933 100644 --- a/tests/expressions_case/tests.py +++ b/tests/expressions_case/tests.py @@ -415,6 +415,16 @@ class CaseExpressionTests(TestCase): self.assertEqual(len(objects), CaseTestModel.objects.count()) self.assertTrue(all(obj.selected == "not selected" for obj in objects)) + def test_annotate_with_full_when(self): + objects = CaseTestModel.objects.annotate( + selected=Case( + When(~Q(pk__in=[]), then=Value("selected")), + default=Value("not selected"), + ) + ) + self.assertEqual(len(objects), CaseTestModel.objects.count()) + self.assertTrue(all(obj.selected == "selected" for obj in objects)) + def test_combined_expression(self): self.assertQuerysetEqual( CaseTestModel.objects.annotate(