mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-23 15:54:16 +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):
|
||||
"""
|
||||
Validates that the input is a decimal number. Returns a Decimal
|
||||
instance. Returns None for empty values. Ensures that there are no more
|
||||
than max_digits in the number, and no more than decimal_places digits
|
||||
after the decimal point.
|
||||
Validate that the input is a decimal number and return a Decimal
|
||||
instance.
|
||||
"""
|
||||
data = smart_text(data).strip()
|
||||
if len(data) > self.MAX_STRING_LENGTH:
|
||||
|
@ -780,6 +778,16 @@ class DecimalField(Field):
|
|||
if value in (decimal.Decimal('Inf'), decimal.Decimal('-Inf')):
|
||||
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()
|
||||
decimals = abs(exponent)
|
||||
# digittuple doesn't include any leading zeros.
|
||||
|
@ -805,16 +813,22 @@ class DecimalField(Field):
|
|||
if not isinstance(value, decimal.Decimal):
|
||||
value = decimal.Decimal(six.text_type(value).strip())
|
||||
|
||||
context = decimal.getcontext().copy()
|
||||
context.prec = self.max_digits
|
||||
quantized = value.quantize(
|
||||
decimal.Decimal('.1') ** self.decimal_places,
|
||||
context=context
|
||||
)
|
||||
quantized = self.quantize(value)
|
||||
|
||||
if not self.coerce_to_string:
|
||||
return 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...
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user