diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index d1f31f0211..f9cafdb4bb 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -392,7 +392,10 @@ class Field(RegisterLookupMixin): if ( self.db_default is NOT_PROVIDED - or isinstance(self.db_default, Value) + or ( + isinstance(self.db_default, Value) + or not hasattr(self.db_default, "resolve_expression") + ) or databases is None ): return [] diff --git a/tests/invalid_models_tests/test_ordinary_fields.py b/tests/invalid_models_tests/test_ordinary_fields.py index e30d411138..1fcf3f708d 100644 --- a/tests/invalid_models_tests/test_ordinary_fields.py +++ b/tests/invalid_models_tests/test_ordinary_fields.py @@ -1207,6 +1207,23 @@ class InvalidDBDefaultTests(TestCase): expected_error = Error(msg=msg, obj=field, id="fields.E012") self.assertEqual(errors, [expected_error]) + def test_literals_not_treated_as_expressions(self): + """ + DatabaseFeatures.supports_expression_defaults = False shouldn't + prevent non-expression literals (integer, float, boolean, etc.) from + being used as database defaults. + """ + + class Model(models.Model): + field = models.FloatField(db_default=1.0) + + field = Model._meta.get_field("field") + with unittest.mock.patch.object( + connection.features, "supports_expression_defaults", False + ): + errors = field.check(databases=self.databases) + self.assertEqual(errors, []) + @isolate_apps("invalid_models_tests") class GeneratedFieldTests(TestCase):