diff --git a/django/db/backends/oracle/features.py b/django/db/backends/oracle/features.py index 8a02e098d6..bb7b2384bd 100644 --- a/django/db/backends/oracle/features.py +++ b/django/db/backends/oracle/features.py @@ -119,6 +119,10 @@ class DatabaseFeatures(BaseDatabaseFeatures): "Oracle doesn't support comparing NCLOB to NUMBER.": { "generic_relations_regress.tests.GenericRelationTests.test_textlink_filter", }, + "DecimalField.db_default doesn't return decimal.Decimal instances on Oracle " + "(#34941).": { + "field_defaults.tests.DefaultTests.test_field_db_defaults_returning", + }, } django_test_expected_failures = { # A bug in Django/oracledb with respect to string handling (#23843). diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 9aa78a281f..b38f8f64ef 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -27,7 +27,7 @@ class SQLiteNumericMixin: sql, params = self.as_sql(compiler, connection, **extra_context) try: if self.output_field.get_internal_type() == "DecimalField": - sql = "CAST(%s AS NUMERIC)" % sql + sql = "(CAST(%s AS NUMERIC))" % sql except FieldError: pass return sql, params diff --git a/tests/field_defaults/models.py b/tests/field_defaults/models.py index 5f9c38a5a4..17191deefb 100644 --- a/tests/field_defaults/models.py +++ b/tests/field_defaults/models.py @@ -10,6 +10,7 @@ field. """ from datetime import datetime +from decimal import Decimal from django.db import models from django.db.models.functions import Coalesce, ExtractYear, Now, Pi @@ -33,6 +34,9 @@ class DBArticle(models.Model): headline = models.CharField(max_length=100, db_default="Default headline") pub_date = models.DateTimeField(db_default=Now()) + cost = models.DecimalField( + max_digits=3, decimal_places=2, db_default=Decimal("3.33") + ) class Meta: required_db_features = {"supports_expression_defaults"} diff --git a/tests/field_defaults/tests.py b/tests/field_defaults/tests.py index 76d01f7a5a..c05d966bdb 100644 --- a/tests/field_defaults/tests.py +++ b/tests/field_defaults/tests.py @@ -1,4 +1,5 @@ from datetime import datetime +from decimal import Decimal from math import pi from django.db import connection @@ -44,6 +45,7 @@ class DefaultTests(TestCase): self.assertIsInstance(a.id, int) self.assertEqual(a.headline, "Default headline") self.assertIsInstance(a.pub_date, datetime) + self.assertEqual(a.cost, Decimal("3.33")) @skipIfDBFeature("can_return_columns_from_insert") @skipUnlessDBFeature("supports_expression_defaults") @@ -54,6 +56,7 @@ class DefaultTests(TestCase): self.assertIsInstance(a.id, int) self.assertEqual(a.headline, "Default headline") self.assertIsInstance(a.pub_date, datetime) + self.assertEqual(a.cost, Decimal("3.33")) def test_null_db_default(self): obj1 = DBDefaults.objects.create() @@ -141,12 +144,12 @@ class DefaultTests(TestCase): articles = [DBArticle(pub_date=pub_date), DBArticle(pub_date=pub_date)] DBArticle.objects.bulk_create(articles) - headlines = DBArticle.objects.values_list("headline", "pub_date") + headlines = DBArticle.objects.values_list("headline", "pub_date", "cost") self.assertSequenceEqual( headlines, [ - ("Default headline", pub_date), - ("Default headline", pub_date), + ("Default headline", pub_date, Decimal("3.33")), + ("Default headline", pub_date, Decimal("3.33")), ], )