summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChinmoy Chakraborty <chinmoy12c@gmail.com>2021-08-21 20:57:15 +0530
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-09-28 13:20:14 +0200
commitb7fd668b37341fc92d67c4854c4f244e10895c9b (patch)
tree4a67b0d614905bdd9010ebb6cb33ca7dcf34a6a4
parent93f3b7a0ba2969109940775a18515728603afac6 (diff)
Fixed #33033 -- Prevented models.DecimalField from accepting NaN values.
-rw-r--r--django/db/models/fields/__init__.py7
-rw-r--r--tests/model_fields/test_decimalfield.py8
2 files changed, 15 insertions, 0 deletions
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index e79f4acf6c..0e72a09e59 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -2,6 +2,7 @@ import collections.abc
import copy
import datetime
import decimal
+import math
import operator
import uuid
import warnings
@@ -1539,6 +1540,12 @@ class DecimalField(Field):
if value is None:
return value
if isinstance(value, float):
+ if math.isnan(value):
+ raise exceptions.ValidationError(
+ self.error_messages['invalid'],
+ code='invalid',
+ params={'value': value},
+ )
return self.context.create_decimal_from_float(value)
try:
return decimal.Decimal(value)
diff --git a/tests/model_fields/test_decimalfield.py b/tests/model_fields/test_decimalfield.py
index 2d96cfd437..ea06ab9fa2 100644
--- a/tests/model_fields/test_decimalfield.py
+++ b/tests/model_fields/test_decimalfield.py
@@ -1,3 +1,4 @@
+import math
from decimal import Decimal
from django.core import validators
@@ -65,6 +66,13 @@ class DecimalFieldTests(TestCase):
bd = BigD.objects.get(pk=bd.pk)
self.assertEqual(bd.d, Decimal('12.9'))
+ def test_save_nan_invalid(self):
+ msg = '“nan” value must be a decimal number.'
+ with self.assertRaisesMessage(ValidationError, msg):
+ BigD.objects.create(d=float('nan'))
+ with self.assertRaisesMessage(ValidationError, msg):
+ BigD.objects.create(d=math.nan)
+
def test_fetch_from_db_without_float_rounding(self):
big_decimal = BigD.objects.create(d=Decimal('.100000000000000000000000000005'))
big_decimal.refresh_from_db()