From c542d0a07237033225c1d57337ca9474a00648f2 Mon Sep 17 00:00:00 2001 From: yakimka Date: Thu, 15 Jul 2021 21:27:59 +0300 Subject: [PATCH] Fixed #32949 -- Restored invalid number handling in DecimalField.validate(). DecimalField must itself validate() values, such as NaN, which cannot be passed to validators, such as MaxValueValidator, during the run_validators() phase. Regression in cc3d24d7d577f174937a0744d886c4c7123cfa85. --- django/forms/fields.py | 11 +++++++++++ docs/releases/3.2.6.txt | 4 +++- tests/forms_tests/field_tests/test_decimalfield.py | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/django/forms/fields.py b/django/forms/fields.py index f1275aa387..65d6a9ec82 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -349,6 +349,17 @@ class DecimalField(IntegerField): raise ValidationError(self.error_messages['invalid'], code='invalid') return value + def validate(self, value): + super().validate(value) + if value in self.empty_values: + return + if not value.is_finite(): + raise ValidationError( + self.error_messages['invalid'], + code='invalid', + params={'value': value}, + ) + def widget_attrs(self, widget): attrs = super().widget_attrs(widget) if isinstance(widget, NumberInput) and 'step' not in widget.attrs: diff --git a/docs/releases/3.2.6.txt b/docs/releases/3.2.6.txt index 426b9c6797..222e169901 100644 --- a/docs/releases/3.2.6.txt +++ b/docs/releases/3.2.6.txt @@ -9,4 +9,6 @@ Django 3.2.6 fixes several bugs in 3.2.5. Bugfixes ======== -* ... +* Fixed a regression in Django 3.2 that caused a crash validating ``"NaN"`` + input with a ``forms.DecimalField`` that had a specified ``max_value`` + (:ticket:`32949`). diff --git a/tests/forms_tests/field_tests/test_decimalfield.py b/tests/forms_tests/field_tests/test_decimalfield.py index d999dab3f3..df5b9052b2 100644 --- a/tests/forms_tests/field_tests/test_decimalfield.py +++ b/tests/forms_tests/field_tests/test_decimalfield.py @@ -49,7 +49,7 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase): self.assertIsNone(f.min_value) def test_enter_a_number_error(self): - f = DecimalField(max_digits=4, decimal_places=2) + f = DecimalField(max_value=1, max_digits=4, decimal_places=2) values = ( '-NaN', 'NaN', '+NaN', '-sNaN', 'sNaN', '+sNaN',