mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-11 12:17:24 +03:00
Refactored DecimalField to allow easier subclassing
This commit is contained in:
parent
b41808b79a
commit
022c4d540b
|
@ -757,10 +757,8 @@ class DecimalField(Field):
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
"""
|
"""
|
||||||
Validates that the input is a decimal number. Returns a Decimal
|
Validate that the input is a decimal number and return a Decimal
|
||||||
instance. Returns None for empty values. Ensures that there are no more
|
instance.
|
||||||
than max_digits in the number, and no more than decimal_places digits
|
|
||||||
after the decimal point.
|
|
||||||
"""
|
"""
|
||||||
data = smart_text(data).strip()
|
data = smart_text(data).strip()
|
||||||
if len(data) > self.MAX_STRING_LENGTH:
|
if len(data) > self.MAX_STRING_LENGTH:
|
||||||
|
@ -780,6 +778,16 @@ class DecimalField(Field):
|
||||||
if value in (decimal.Decimal('Inf'), decimal.Decimal('-Inf')):
|
if value in (decimal.Decimal('Inf'), decimal.Decimal('-Inf')):
|
||||||
self.fail('invalid')
|
self.fail('invalid')
|
||||||
|
|
||||||
|
return self.validate_precision(value)
|
||||||
|
|
||||||
|
def validate_precision(self, value):
|
||||||
|
"""
|
||||||
|
Ensure that there are no more than max_digits in the number, and no
|
||||||
|
more than decimal_places digits after the decimal point.
|
||||||
|
|
||||||
|
Override this method to disable the precision validation for input
|
||||||
|
values or to enhance it in any way you need to.
|
||||||
|
"""
|
||||||
sign, digittuple, exponent = value.as_tuple()
|
sign, digittuple, exponent = value.as_tuple()
|
||||||
decimals = abs(exponent)
|
decimals = abs(exponent)
|
||||||
# digittuple doesn't include any leading zeros.
|
# digittuple doesn't include any leading zeros.
|
||||||
|
@ -805,16 +813,22 @@ class DecimalField(Field):
|
||||||
if not isinstance(value, decimal.Decimal):
|
if not isinstance(value, decimal.Decimal):
|
||||||
value = decimal.Decimal(six.text_type(value).strip())
|
value = decimal.Decimal(six.text_type(value).strip())
|
||||||
|
|
||||||
context = decimal.getcontext().copy()
|
quantized = self.quantize(value)
|
||||||
context.prec = self.max_digits
|
|
||||||
quantized = value.quantize(
|
|
||||||
decimal.Decimal('.1') ** self.decimal_places,
|
|
||||||
context=context
|
|
||||||
)
|
|
||||||
if not self.coerce_to_string:
|
if not self.coerce_to_string:
|
||||||
return quantized
|
return quantized
|
||||||
return '{0:f}'.format(quantized)
|
return '{0:f}'.format(quantized)
|
||||||
|
|
||||||
|
def quantize(self, value):
|
||||||
|
"""
|
||||||
|
Quantize the decimal value to the configured precision.
|
||||||
|
"""
|
||||||
|
context = decimal.getcontext().copy()
|
||||||
|
context.prec = self.max_digits
|
||||||
|
return value.quantize(
|
||||||
|
decimal.Decimal('.1') ** self.decimal_places,
|
||||||
|
context=context)
|
||||||
|
|
||||||
|
|
||||||
# Date & time fields...
|
# Date & time fields...
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user