Fixed #31663 -- Made DecimalField.to_python() handle non-numeric invalid values.

This commit is contained in:
Sasha Pachev 2020-06-05 13:13:36 -06:00 committed by GitHub
parent 433dd737f9
commit 38a21f2d9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 4 deletions

View File

@ -1501,7 +1501,7 @@ class DecimalField(Field):
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)
except decimal.InvalidOperation: except (decimal.InvalidOperation, TypeError, ValueError):
raise exceptions.ValidationError( raise exceptions.ValidationError(
self.error_messages['invalid'], self.error_messages['invalid'],
code='invalid', code='invalid',

View File

@ -21,9 +21,24 @@ class DecimalFieldTests(TestCase):
# Uses default rounding of ROUND_HALF_EVEN. # Uses default rounding of ROUND_HALF_EVEN.
self.assertEqual(f.to_python(2.0625), Decimal('2.062')) self.assertEqual(f.to_python(2.0625), Decimal('2.062'))
self.assertEqual(f.to_python(2.1875), Decimal('2.188')) self.assertEqual(f.to_python(2.1875), Decimal('2.188'))
msg = '“abc” value must be a decimal number.'
with self.assertRaisesMessage(ValidationError, msg): def test_invalid_value(self):
f.to_python('abc') field = models.DecimalField(max_digits=4, decimal_places=2)
msg = '%s” value must be a decimal number.'
tests = [
(),
[],
{},
set(),
object(),
complex(),
'non-numeric string',
b'non-numeric byte-string',
]
for value in tests:
with self.subTest(value):
with self.assertRaisesMessage(ValidationError, msg % (value,)):
field.clean(value, None)
def test_default(self): def test_default(self):
f = models.DecimalField(default=Decimal('0.00')) f = models.DecimalField(default=Decimal('0.00'))