From f783a990725fbfce17ef827d3b55ef702535ae96 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Sun, 12 Jul 2020 00:49:43 -0400 Subject: [PATCH] Refs #25425 -- Allowed unresolved Value() instances to be compiled. Previously unresolved Value() instances were only allowed to be compiled if they weren't initialized with an output_field. Given the usage of unresolved Value() instances is relatively common in as_sql() overrides it's less controversial to add explicit support for this previously undefined behavior now and revisit whether or not it should be deprecated in the future. --- django/db/models/expressions.py | 4 ++++ tests/expressions/tests.py | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 07e1641dc1..8cceb7d966 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -676,6 +676,10 @@ class Func(SQLiteNumericMixin, Expression): class Value(Expression): """Represent a wrapped value as a node within an expression.""" + # Provide a default value for `for_save` in order to allow unresolved + # instances to be compiled until a decision is taken in #25425. + for_save = False + def __init__(self, value, output_field=None): """ Arguments: diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 47a410268e..42b8c8f34b 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -1703,6 +1703,14 @@ class ValueTests(TestCase): with self.assertRaisesMessage(ValueError, msg): ExpressionList() + def test_compile_unresolved(self): + # This test might need to be revisited later on if #25425 is enforced. + compiler = Time.objects.all().query.get_compiler(connection=connection) + value = Value('foo') + self.assertEqual(value.as_sql(compiler, connection), ('%s', ['foo'])) + value = Value('foo', output_field=CharField()) + self.assertEqual(value.as_sql(compiler, connection), ('%s', ['foo'])) + class FieldTransformTests(TestCase):