feat: FloatField optionally validates that the number is no less than or equals to a given value.

This commit is contained in:
Anes Foufa 2020-07-28 17:26:12 +02:00
parent a03b356e28
commit 97b6d0f09c
4 changed files with 46 additions and 8 deletions

View File

@ -280,7 +280,8 @@ Corresponds to `django.db.models.fields.FloatField`.
- `max_value` Validate that the number provided is no greater than this value. - `max_value` Validate that the number provided is no greater than this value.
- `min_value` Validate that the number provided is no less than this value. - `min_value` Validate that the number provided is no less than this value.
- `exclusive_min` If true, validate that the number provided is no greater than or equals `min_value`. - `exclusive_min` If true, validate that the number provided is no greater than or equals to `min_value`.
- `exclusive_max` If true, validate that the number provided is no less than or equals to `max_value`.
## DecimalField ## DecimalField

View File

@ -38,7 +38,8 @@ from rest_framework.exceptions import ErrorDetail, ValidationError
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
from rest_framework.utils import html, humanize_datetime, json, representation from rest_framework.utils import html, humanize_datetime, json, representation
from rest_framework.utils.formatting import lazy_format from rest_framework.utils.formatting import lazy_format
from rest_framework.validators import ExclusiveLMinValueValidator, ProhibitSurrogateCharactersValidator from rest_framework.validators import (ExclusiveMaxValueValidator, ExclusiveMinValueValidator,
ProhibitSurrogateCharactersValidator)
class empty: class empty:
@ -967,6 +968,7 @@ class FloatField(Field):
default_error_messages = { default_error_messages = {
'invalid': _('A valid number is required.'), 'invalid': _('A valid number is required.'),
'max_value': _('Ensure this value is less than or equal to {max_value}.'), 'max_value': _('Ensure this value is less than or equal to {max_value}.'),
'exclusive_max_value': _('Ensure this value is less than {max_value}.'),
'min_value': _('Ensure this value is greater than or equal to {min_value}.'), 'min_value': _('Ensure this value is greater than or equal to {min_value}.'),
'exclusive_min_value': _('Ensure this value is greater than {min_value}.'), 'exclusive_min_value': _('Ensure this value is greater than {min_value}.'),
'max_string_length': _('String value too large.') 'max_string_length': _('String value too large.')
@ -977,16 +979,22 @@ class FloatField(Field):
self.max_value = kwargs.pop('max_value', None) self.max_value = kwargs.pop('max_value', None)
self.min_value = kwargs.pop('min_value', None) self.min_value = kwargs.pop('min_value', None)
self.exclusive_min = kwargs.pop("exclusive_min", False) self.exclusive_min = kwargs.pop("exclusive_min", False)
self.exclusive_max = kwargs.pop("exclusive_max", False)
super().__init__(**kwargs) super().__init__(**kwargs)
if self.max_value is not None: if self.max_value is not None:
message = lazy_format(self.error_messages['max_value'], max_value=self.max_value) if self.exclusive_max:
self.validators.append( message = lazy_format(self.error_messages["exclusive_max_value"], max_value=self.max_value)
MaxValueValidator(self.max_value, message=message)) self.validators.append(
ExclusiveMaxValueValidator(self.max_value, message=message))
else:
message = lazy_format(self.error_messages['max_value'], max_value=self.max_value)
self.validators.append(
MaxValueValidator(self.max_value, message=message))
if self.min_value is not None: if self.min_value is not None:
if self.exclusive_min: if self.exclusive_min:
message = lazy_format(self.error_messages["exclusive_min_value"], min_value=self.min_value) message = lazy_format(self.error_messages["exclusive_min_value"], min_value=self.min_value)
self.validators.append( self.validators.append(
ExclusiveLMinValueValidator(self.min_value, message=message)) ExclusiveMinValueValidator(self.min_value, message=message))
else: else:
message = lazy_format(self.error_messages['min_value'], min_value=self.min_value) message = lazy_format(self.error_messages['min_value'], min_value=self.min_value)
self.validators.append( self.validators.append(

View File

@ -281,9 +281,17 @@ class UniqueForYearValidator(BaseUniqueForValidator):
return qs_filter(queryset, **filter_kwargs) return qs_filter(queryset, **filter_kwargs)
class ExclusiveLMinValueValidator(BaseValidator): class ExclusiveMinValueValidator(BaseValidator):
message = _('Ensure this value is greater than %(limit_value)s.') message = _('Ensure this value is greater than %(limit_value)s.')
code = "exclusive_min_value" code = "exclusive_min_value"
def compare(self, a, b): def compare(self, a, b):
return a <= b return a <= b
class ExclusiveMaxValueValidator(BaseValidator):
message = _('Ensure this value is lesser than %(limit_value)s.')
code = "exclusive_max_value"
def compare(self, a, b):
return a >= b

View File

@ -1078,7 +1078,7 @@ class TestMinMaxFloatField(FieldValues):
class TestExclusiveMinFloatField(FieldValues): class TestExclusiveMinFloatField(FieldValues):
""" """
Valid and invalid values for 'FloatField' with exclusive_min limits. Valid and invalid values for 'FloatField' with exclusive_min limit.
""" """
valid_inputs = { valid_inputs = {
'1.01': 1.01, '1.01': 1.01,
@ -1096,6 +1096,27 @@ class TestExclusiveMinFloatField(FieldValues):
field = serializers.FloatField(min_value=1, exclusive_min=True) field = serializers.FloatField(min_value=1, exclusive_min=True)
class TestExclusiveMaxFloatField(FieldValues):
"""
Valid and invalid values for 'FloatField' with exclusive_max limit.
"""
valid_inputs = {
'1': 1,
'2.9': 2.9,
1: 1,
2.9: 2.9,
1.0: 1.0,
}
invalid_inputs = {
3: ['Ensure this value is less than 3.'],
'3': ['Ensure this value is less than 3.'],
'3.0': ['Ensure this value is less than 3.'],
}
outputs = {}
field = serializers.FloatField(max_value=3, exclusive_max=True)
class TestDecimalField(FieldValues): class TestDecimalField(FieldValues):
""" """
Valid and invalid values for `DecimalField`. Valid and invalid values for `DecimalField`.