From 7cd89c6f0e84900876cd5a9f6b525e2b171ed00c Mon Sep 17 00:00:00 2001 From: Evgeny Panfilov Date: Thu, 1 Jul 2021 15:47:52 +0300 Subject: [PATCH] fix empty string as a value for a validated DecimalField (#8064) --- rest_framework/fields.py | 8 +++++--- tests/test_fields.py | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index e4be54751..bedc02b94 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1046,6 +1046,11 @@ class DecimalField(Field): 'Invalid rounding option %s. Valid values for rounding are: %s' % (rounding, valid_roundings)) self.rounding = rounding + def validate_empty_values(self, data): + if smart_str(data).strip() == '' and self.allow_null: + return (True, None) + return super().validate_empty_values(data) + def to_internal_value(self, data): """ Validate that the input is a decimal number and return a Decimal @@ -1063,9 +1068,6 @@ 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(): diff --git a/tests/test_fields.py b/tests/test_fields.py index 78a9effb8..d99ca9c40 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -1163,6 +1163,30 @@ class TestMinMaxDecimalField(FieldValues): ) +class TestAllowEmptyStrDecimalFieldWithValidators(FieldValues): + """ + Check that empty string ('', ' ') is acceptable value for the DecimalField + if allow_null=True and there are max/min validators + """ + valid_inputs = { + None: None, + '': None, + ' ': None, + ' ': None, + 5: Decimal('5'), + '0': Decimal('0'), + '10': Decimal('10'), + } + invalid_inputs = { + -1: ['Ensure this value is greater than or equal to 0.'], + 11: ['Ensure this value is less than or equal to 10.'], + } + outputs = { + None: '', + } + field = serializers.DecimalField(max_digits=3, decimal_places=1, allow_null=True, min_value=0, max_value=10) + + class TestNoMaxDigitsDecimalField(FieldValues): field = serializers.DecimalField( max_value=100, min_value=0,