From 8b1acc0440418ac8f45ba48e2dfcf5126c83341b Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Tue, 7 Nov 2023 21:47:37 -0500 Subject: [PATCH] Refs #30446, Refs #34944 -- Fixed crash when adding GeneratedField with string Value(). This should allow smarter output_field inferring in functions dealing with text expressions. Regression in f333e3513e8bdf5ffeb6eeb63021c230082e6f95. --- django/db/models/expressions.py | 2 +- tests/expressions/tests.py | 1 + tests/schema/tests.py | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 3a0c75ebf2c..4d4f3c4ecce 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -1082,7 +1082,7 @@ class Value(SQLiteNumericMixin, Expression): def _resolve_output_field(self): if isinstance(self.value, str): - return fields.CharField() + return fields.CharField(max_length=len(self.value)) if isinstance(self.value, bool): return fields.BooleanField() if isinstance(self.value, int): diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 073e2e92583..9743d024b1b 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -2227,6 +2227,7 @@ class ValueTests(TestCase): with self.subTest(type=type(value)): expr = Value(value) self.assertIsInstance(expr.output_field, output_field_type) + self.assertEqual(Value("foo").output_field.max_length, 3) def test_resolve_output_field_failure(self): msg = "Cannot resolve expression type, unknown output_field" diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 72f90c934b7..1298b32caf8 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -842,6 +842,23 @@ class SchemaTests(TransactionTestCase): False, ) + @isolate_apps("schema") + @skipUnlessDBFeature("supports_stored_generated_columns") + def test_add_generated_field_with_string_value(self): + class GeneratedFieldStringValueModel(Model): + value = GeneratedField(expression=Value("static string"), db_persist=True) + + class Meta: + app_label = "schema" + + with CaptureQueriesContext(connection) as ctx: + with connection.schema_editor() as editor: + editor.create_model(GeneratedFieldStringValueModel) + self.assertIs( + any("None" in query["sql"] for query in ctx.captured_queries), + False, + ) + @isolate_apps("schema") @skipUnlessDBFeature("supports_stored_generated_columns") def test_add_generated_field_with_output_field(self):