Fixed #33033 -- Prevented models.DecimalField from accepting NaN values.
This commit is contained in:
parent
93f3b7a0ba
commit
b7fd668b37
|
@ -2,6 +2,7 @@ import collections.abc
|
||||||
import copy
|
import copy
|
||||||
import datetime
|
import datetime
|
||||||
import decimal
|
import decimal
|
||||||
|
import math
|
||||||
import operator
|
import operator
|
||||||
import uuid
|
import uuid
|
||||||
import warnings
|
import warnings
|
||||||
|
@ -1539,6 +1540,12 @@ class DecimalField(Field):
|
||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
if isinstance(value, float):
|
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)
|
return self.context.create_decimal_from_float(value)
|
||||||
try:
|
try:
|
||||||
return decimal.Decimal(value)
|
return decimal.Decimal(value)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import math
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
|
@ -65,6 +66,13 @@ class DecimalFieldTests(TestCase):
|
||||||
bd = BigD.objects.get(pk=bd.pk)
|
bd = BigD.objects.get(pk=bd.pk)
|
||||||
self.assertEqual(bd.d, Decimal('12.9'))
|
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):
|
def test_fetch_from_db_without_float_rounding(self):
|
||||||
big_decimal = BigD.objects.create(d=Decimal('.100000000000000000000000000005'))
|
big_decimal = BigD.objects.create(d=Decimal('.100000000000000000000000000005'))
|
||||||
big_decimal.refresh_from_db()
|
big_decimal.refresh_from_db()
|
||||||
|
|
Loading…
Reference in New Issue