Respect allow_null=True on DecimalFields (#7718)

* Handle None in to_representation()
* Return None as '' in to_representation() when coerce_to_string=True
* Handle '' as None in to_internal_value(), for symmetry with
  to_representation(), and because the empty concept doesn't make sense
  for Decimal.
This commit is contained in:
David Kerkeslager 2021-03-09 05:49:03 -05:00 committed by GitHub
parent a89a6427d3
commit 05512160ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 0 deletions

View File

@ -1063,6 +1063,9 @@ class DecimalField(Field):
try:
value = decimal.Decimal(data)
except decimal.DecimalException:
if data == '' and self.allow_null:
return None
self.fail('invalid')
if value.is_nan():
@ -1112,6 +1115,12 @@ class DecimalField(Field):
def to_representation(self, value):
coerce_to_string = getattr(self, 'coerce_to_string', api_settings.COERCE_DECIMAL_TO_STRING)
if value is None:
if coerce_to_string:
return ''
else:
return None
if not isinstance(value, decimal.Decimal):
value = decimal.Decimal(str(value).strip())

View File

@ -1090,6 +1090,9 @@ class TestDecimalField(FieldValues):
'2E+1': Decimal('20'),
}
invalid_inputs = (
(None, ["This field may not be null."]),
('', ["A valid number is required."]),
(' ', ["A valid number is required."]),
('abc', ["A valid number is required."]),
(Decimal('Nan'), ["A valid number is required."]),
(Decimal('Snan'), ["A valid number is required."]),
@ -1115,6 +1118,32 @@ class TestDecimalField(FieldValues):
field = serializers.DecimalField(max_digits=3, decimal_places=1)
class TestAllowNullDecimalField(FieldValues):
valid_inputs = {
None: None,
'': None,
' ': None,
}
invalid_inputs = {}
outputs = {
None: '',
}
field = serializers.DecimalField(max_digits=3, decimal_places=1, allow_null=True)
class TestAllowNullNoStringCoercionDecimalField(FieldValues):
valid_inputs = {
None: None,
'': None,
' ': None,
}
invalid_inputs = {}
outputs = {
None: None,
}
field = serializers.DecimalField(max_digits=3, decimal_places=1, allow_null=True, coerce_to_string=False)
class TestMinMaxDecimalField(FieldValues):
"""
Valid and invalid values for `DecimalField` with min and max limits.