mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-05 04:50:12 +03:00
Add the "localize" and "coerce_to_string" constructor options to the FloatField like it is done for the DecimalField, in order to use the user current local to serialise and deserialise the float value if required.
This commit is contained in:
parent
ddfce425fa
commit
38b306426c
|
@ -25,7 +25,9 @@ from django.utils.dateparse import (
|
|||
)
|
||||
from django.utils.duration import duration_string
|
||||
from django.utils.encoding import is_protected_type, smart_text
|
||||
from django.utils.formats import localize_input, sanitize_separators
|
||||
from django.utils.formats import (
|
||||
localize_input, number_format, sanitize_separators
|
||||
)
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.ipv6 import clean_ipv6_address
|
||||
from django.utils.timezone import utc
|
||||
|
@ -920,6 +922,10 @@ class FloatField(Field):
|
|||
def __init__(self, **kwargs):
|
||||
self.max_value = kwargs.pop('max_value', None)
|
||||
self.min_value = kwargs.pop('min_value', None)
|
||||
self.localize = kwargs.pop('localize', False)
|
||||
self.coerce_to_string = kwargs.pop('coerce_to_string', None)
|
||||
if self.localize:
|
||||
self.coerce_to_string = True
|
||||
super(FloatField, self).__init__(**kwargs)
|
||||
if self.max_value is not None:
|
||||
message = self.error_messages['max_value'].format(max_value=self.max_value)
|
||||
|
@ -930,7 +936,12 @@ class FloatField(Field):
|
|||
|
||||
def to_internal_value(self, data):
|
||||
|
||||
if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH:
|
||||
data = smart_text(data).strip()
|
||||
|
||||
if self.localize:
|
||||
data = sanitize_separators(data)
|
||||
|
||||
if len(data) > self.MAX_STRING_LENGTH:
|
||||
self.fail('max_string_length')
|
||||
|
||||
try:
|
||||
|
@ -939,6 +950,10 @@ class FloatField(Field):
|
|||
self.fail('invalid')
|
||||
|
||||
def to_representation(self, value):
|
||||
if self.localize:
|
||||
return number_format(value)
|
||||
if self.coerce_to_string:
|
||||
return str(float(value))
|
||||
return float(value)
|
||||
|
||||
|
||||
|
|
|
@ -922,6 +922,36 @@ class TestMinMaxFloatField(FieldValues):
|
|||
field = serializers.FloatField(min_value=1, max_value=3)
|
||||
|
||||
|
||||
class TestCoerceToStringFloatField(FieldValues):
|
||||
valid_inputs = {}
|
||||
invalid_inputs = {}
|
||||
outputs = {
|
||||
'1': str(1.0),
|
||||
'0': str(0.0),
|
||||
1: str(1.0),
|
||||
0: str(0.0),
|
||||
1.5: str(1.5),
|
||||
}
|
||||
field = serializers.FloatField(coerce_to_string=True)
|
||||
|
||||
|
||||
class TestLocalizedFloatField(TestCase):
|
||||
@override_settings(USE_L10N=True, LANGUAGE_CODE='it')
|
||||
def test_to_internal_value(self):
|
||||
field = serializers.FloatField(localize=True)
|
||||
self.assertEqual(field.to_internal_value('1,5'), 1.5)
|
||||
|
||||
@override_settings(USE_L10N=True, LANGUAGE_CODE=None, DECIMAL_SEPARATOR=',', THOUSAND_SEPARATOR='\'',
|
||||
NUMBER_GROUPING=3, USE_THOUSAND_SEPARATOR=True)
|
||||
def test_to_representation(self):
|
||||
field = serializers.FloatField(localize=True)
|
||||
self.assertEqual(field.to_representation(1000.75), '1\'000,75')
|
||||
|
||||
def test_localize_forces_coerce_to_string(self):
|
||||
field = serializers.FloatField(localize=True)
|
||||
self.assertTrue(isinstance(field.to_representation(3), six.string_types))
|
||||
|
||||
|
||||
class TestDecimalField(FieldValues):
|
||||
"""
|
||||
Valid and invalid values for `DecimalField`.
|
||||
|
|
Loading…
Reference in New Issue
Block a user