summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/models/expressions.py14
-rw-r--r--tests/expressions/tests.py10
2 files changed, 23 insertions, 1 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 6b90a42cf1..baa91cc2c1 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -1141,7 +1141,7 @@ class Func(SQLiteNumericMixin, Expression):
@deconstructible(path="django.db.models.Value")
-class Value(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
@@ -1182,6 +1182,18 @@ class Value(SQLiteNumericMixin, Expression):
return "NULL", []
return "%s", [val]
+ def as_sqlite(self, compiler, connection, **extra_context):
+ sql, params = self.as_sql(compiler, connection, **extra_context)
+ try:
+ if self.output_field.get_internal_type() == "DecimalField":
+ if isinstance(self.value, Decimal):
+ sql = "(CAST(%s AS REAL))" % sql
+ else:
+ sql = "(CAST(%s AS NUMERIC))" % sql
+ except FieldError:
+ pass
+ return sql, params
+
def resolve_expression(
self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False
):
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
index 981d84e9e8..02126fa896 100644
--- a/tests/expressions/tests.py
+++ b/tests/expressions/tests.py
@@ -137,6 +137,16 @@ class BasicExpressionsTests(TestCase):
)
self.assertEqual(companies["result"], 2395)
+ def test_decimal_division_literal_value(self):
+ """
+ Division with a literal Decimal value preserves precision.
+ """
+ num = Number.objects.create(integer=2)
+ obj = Number.objects.annotate(
+ val=F("integer") / Value(Decimal("3.0"), output_field=DecimalField())
+ ).get(pk=num.pk)
+ self.assertAlmostEqual(obj.val, Decimal("0.6667"), places=4)
+
def test_annotate_values_filter(self):
companies = (
Company.objects.annotate(