mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-28 20:44:03 +03:00
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:
parent
a89a6427d3
commit
05512160ab
|
@ -1063,6 +1063,9 @@ class DecimalField(Field):
|
||||||
try:
|
try:
|
||||||
value = decimal.Decimal(data)
|
value = decimal.Decimal(data)
|
||||||
except decimal.DecimalException:
|
except decimal.DecimalException:
|
||||||
|
if data == '' and self.allow_null:
|
||||||
|
return None
|
||||||
|
|
||||||
self.fail('invalid')
|
self.fail('invalid')
|
||||||
|
|
||||||
if value.is_nan():
|
if value.is_nan():
|
||||||
|
@ -1112,6 +1115,12 @@ class DecimalField(Field):
|
||||||
def to_representation(self, value):
|
def to_representation(self, value):
|
||||||
coerce_to_string = getattr(self, 'coerce_to_string', api_settings.COERCE_DECIMAL_TO_STRING)
|
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):
|
if not isinstance(value, decimal.Decimal):
|
||||||
value = decimal.Decimal(str(value).strip())
|
value = decimal.Decimal(str(value).strip())
|
||||||
|
|
||||||
|
|
|
@ -1090,6 +1090,9 @@ class TestDecimalField(FieldValues):
|
||||||
'2E+1': Decimal('20'),
|
'2E+1': Decimal('20'),
|
||||||
}
|
}
|
||||||
invalid_inputs = (
|
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."]),
|
('abc', ["A valid number is required."]),
|
||||||
(Decimal('Nan'), ["A valid number is required."]),
|
(Decimal('Nan'), ["A valid number is required."]),
|
||||||
(Decimal('Snan'), ["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)
|
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):
|
class TestMinMaxDecimalField(FieldValues):
|
||||||
"""
|
"""
|
||||||
Valid and invalid values for `DecimalField` with min and max limits.
|
Valid and invalid values for `DecimalField` with min and max limits.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user