summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSasha Pachev <sasha@asksasha.com>2020-06-05 13:13:36 -0600
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-06-05 21:14:33 +0200
commit21adaffb6ebe7513c355f49a1628d11df5825800 (patch)
tree681e2737c0fa49788cea0fa7941fa7ac235dfd2e
parent031a082d41ed86a75e5a0b53d9fcdfb3e3a6589f (diff)
[3.1.x] Fixed #31663 -- Made DecimalField.to_python() handle non-numeric invalid values.
Backport of 38a21f2d9ed4f556af934498ec6a242f6a20418a from master
-rw-r--r--django/db/models/fields/__init__.py2
-rw-r--r--tests/model_fields/test_decimalfield.py21
2 files changed, 19 insertions, 4 deletions
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 0fd69059ee..28374272f4 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -1501,7 +1501,7 @@ class DecimalField(Field):
return self.context.create_decimal_from_float(value)
try:
return decimal.Decimal(value)
- except decimal.InvalidOperation:
+ except (decimal.InvalidOperation, TypeError, ValueError):
raise exceptions.ValidationError(
self.error_messages['invalid'],
code='invalid',
diff --git a/tests/model_fields/test_decimalfield.py b/tests/model_fields/test_decimalfield.py
index e284005aa0..729b5e570a 100644
--- a/tests/model_fields/test_decimalfield.py
+++ b/tests/model_fields/test_decimalfield.py
@@ -21,9 +21,24 @@ class DecimalFieldTests(TestCase):
# Uses default rounding of ROUND_HALF_EVEN.
self.assertEqual(f.to_python(2.0625), Decimal('2.062'))
self.assertEqual(f.to_python(2.1875), Decimal('2.188'))
- msg = '“abc” value must be a decimal number.'
- with self.assertRaisesMessage(ValidationError, msg):
- f.to_python('abc')
+
+ def test_invalid_value(self):
+ 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):
f = models.DecimalField(default=Decimal('0.00'))