Skip to content

Commit 125ad42

Browse files
authored
Accept integers as min/max values of DecimalField (#9515)
* Use Decimal for min/max values of DecimalField in tests * Update docs to mention that min/max values should be Decimal objects * Accept integer values for DecimalField min and max values * Update expected error messages in tests * Update expected warning message in tests
1 parent f593f57 commit 125ad42

File tree

3 files changed

+12
-12
lines changed

3 files changed

+12
-12
lines changed

docs/api-guide/fields.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ Corresponds to `django.db.models.fields.DecimalField`.
291291
* `max_digits` The maximum number of digits allowed in the number. It must be either `None` or an integer greater than or equal to `decimal_places`.
292292
* `decimal_places` The number of decimal places to store with the number.
293293
* `coerce_to_string` Set to `True` if string values should be returned for the representation, or `False` if `Decimal` objects should be returned. Defaults to the same value as the `COERCE_DECIMAL_TO_STRING` settings key, which will be `True` unless overridden. If `Decimal` objects are returned by the serializer, then the final output format will be determined by the renderer. Note that setting `localize` will force the value to `True`.
294-
* `max_value` Validate that the number provided is no greater than this value.
295-
* `min_value` Validate that the number provided is no less than this value.
294+
* `max_value` Validate that the number provided is no greater than this value. Should be an integer or `Decimal` object.
295+
* `min_value` Validate that the number provided is no less than this value. Should be an integer or `Decimal` object.
296296
* `localize` Set to `True` to enable localization of input and output based on the current locale. This will also force `coerce_to_string` to `True`. Defaults to `False`. Note that data formatting is enabled if you have set `USE_L10N=True` in your settings file.
297297
* `rounding` Sets the rounding mode used when quantizing to the configured precision. Valid values are [`decimal` module rounding modes][python-decimal-rounding-modes]. Defaults to `None`.
298298
* `normalize_output` Will normalize the decimal value when serialized. This will strip all trailing zeroes and change the value's precision to the minimum required precision to be able to represent the value without losing data. Defaults to `False`.

rest_framework/fields.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -986,10 +986,10 @@ def __init__(self, max_digits, decimal_places, coerce_to_string=None, max_value=
986986
self.max_value = max_value
987987
self.min_value = min_value
988988

989-
if self.max_value is not None and not isinstance(self.max_value, decimal.Decimal):
990-
warnings.warn("max_value should be a Decimal instance.")
991-
if self.min_value is not None and not isinstance(self.min_value, decimal.Decimal):
992-
warnings.warn("min_value should be a Decimal instance.")
989+
if self.max_value is not None and not isinstance(self.max_value, (int, decimal.Decimal)):
990+
warnings.warn("max_value should be an integer or Decimal instance.")
991+
if self.min_value is not None and not isinstance(self.min_value, (int, decimal.Decimal)):
992+
warnings.warn("min_value should be an integer or Decimal instance.")
993993

994994
if self.max_digits is not None and self.decimal_places is not None:
995995
self.max_whole_digits = self.max_digits - self.decimal_places

tests/test_fields.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1245,13 +1245,13 @@ class TestMinMaxDecimalField(FieldValues):
12451245
'20.0': Decimal('20.0'),
12461246
}
12471247
invalid_inputs = {
1248-
'9.9': ['Ensure this value is greater than or equal to 10.'],
1249-
'20.1': ['Ensure this value is less than or equal to 20.'],
1248+
'9.9': ['Ensure this value is greater than or equal to 10.0.'],
1249+
'20.1': ['Ensure this value is less than or equal to 20.0.'],
12501250
}
12511251
outputs = {}
12521252
field = serializers.DecimalField(
12531253
max_digits=3, decimal_places=1,
1254-
min_value=10, max_value=20
1254+
min_value=10.0, max_value=20.0
12551255
)
12561256

12571257
def test_warning_when_not_decimal_types(self, caplog):
@@ -1260,14 +1260,14 @@ def test_warning_when_not_decimal_types(self, caplog):
12601260

12611261
serializers.DecimalField(
12621262
max_digits=3, decimal_places=1,
1263-
min_value=10, max_value=20
1263+
min_value=10.0, max_value=20.0
12641264
)
12651265

12661266
assert len(w) == 2
12671267
assert all(issubclass(i.category, UserWarning) for i in w)
12681268

1269-
assert 'max_value should be a Decimal instance' in str(w[0].message)
1270-
assert 'min_value should be a Decimal instance' in str(w[1].message)
1269+
assert 'max_value should be an integer or Decimal instance' in str(w[0].message)
1270+
assert 'min_value should be an integer or Decimal instance' in str(w[1].message)
12711271

12721272

12731273
class TestAllowEmptyStrDecimalFieldWithValidators(FieldValues):

0 commit comments

Comments
 (0)