This commit is contained in:
trangttt 2017-11-06 08:10:52 +00:00 committed by GitHub
commit fe7faf6433
2 changed files with 24 additions and 1 deletions

View File

@ -997,7 +997,7 @@ class DecimalField(Field):
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
def __init__(self, max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None,
localize=False, **kwargs):
localize=False, rounding=None, **kwargs):
self.max_digits = max_digits
self.decimal_places = decimal_places
self.localize = localize
@ -1029,6 +1029,12 @@ class DecimalField(Field):
self.validators.append(
MinValueValidator(self.min_value, message=message))
if rounding is not None:
valid_roundings = [v for k, v in vars(decimal).items() if k.startswith('ROUND_')]
assert rounding in valid_roundings, (
'Invalid rounding option %s. Valid values for rounding are: %s' % (rounding, valid_roundings))
self.rounding = rounding
def to_internal_value(self, data):
"""
Validate that the input is a decimal number and return a Decimal
@ -1121,6 +1127,7 @@ class DecimalField(Field):
context.prec = self.max_digits
return value.quantize(
decimal.Decimal('.1') ** self.decimal_places,
rounding=self.rounding,
context=context
)

View File

@ -1092,6 +1092,22 @@ class TestNoDecimalPlaces(FieldValues):
field = serializers.DecimalField(max_digits=6, decimal_places=None)
class TestRoundingDecimalField(TestCase):
def test_valid_rounding(self):
field = serializers.DecimalField(max_digits=4, decimal_places=2, rounding='ROUND_UP')
assert field.to_representation(Decimal('1.234')) == '1.24'
field = serializers.DecimalField(max_digits=4, decimal_places=2, rounding='ROUND_DOWN')
assert field.to_representation(Decimal('1.234')) == '1.23'
def test_invalid_rounding(self):
with pytest.raises(AssertionError) as excinfo:
serializers.DecimalField(max_digits=1, decimal_places=1, rounding='ROUND_UNKNOWN')
assert 'Invalid rounding option' in str(excinfo.value)
# Date & time serializers...
class TestDateField(FieldValues):