[4.0.x] Fixed #33033 -- Prevented models.DecimalField from accepting NaN values.

Backport of b7fd668b37 from main
This commit is contained in:
Chinmoy Chakraborty 2021-08-21 20:57:15 +05:30 committed by Mariusz Felisiak
parent a9479202d7
commit 6f31041794
2 changed files with 15 additions and 0 deletions

View File

@ -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)

View File

@ -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()