From bde814142a933bd96c3fa54a64cb1f74a575bb38 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Thu, 6 Apr 2017 17:34:00 +0200 Subject: [PATCH] Fixed #22654 -- Broken decimal validation --- django/utils/formats.py | 2 +- docs/releases/2.0.txt | 4 ++++ .../field_tests/test_decimalfield.py | 17 ++++++++++++++++- .../forms_tests/field_tests/test_floatfield.py | 16 ++++++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/django/utils/formats.py b/django/utils/formats.py index 3cb0c0420c..aaf1c2ddd5 100644 --- a/django/utils/formats.py +++ b/django/utils/formats.py @@ -240,7 +240,7 @@ def sanitize_separators(value): Sanitize a value according to the current decimal and thousand separator setting. Used with form field input. """ - if settings.USE_L10N and isinstance(value, str): + if isinstance(value, str): parts = [] decimal_separator = get_format('DECIMAL_SEPARATOR') if decimal_separator in value: diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index f21d53cd8a..4babd84773 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -157,6 +157,10 @@ Forms HTML attributes for the ``DateInput`` and ``TimeInput`` (or hidden) subwidgets. +* :class:`~django.forms.FloatField` and :class:`~django.forms.DecimalField` + now handle :setting:`DECIMAL_SEPARATOR` and :setting:`THOUSAND_SEPARATOR` + correctly when :setting:`USE_L10N` is off. + Generic Views ~~~~~~~~~~~~~ diff --git a/tests/forms_tests/field_tests/test_decimalfield.py b/tests/forms_tests/field_tests/test_decimalfield.py index c8fd95fd68..1d5d27c8a0 100644 --- a/tests/forms_tests/field_tests/test_decimalfield.py +++ b/tests/forms_tests/field_tests/test_decimalfield.py @@ -1,7 +1,7 @@ import decimal from django.forms import DecimalField, NumberInput, ValidationError, Widget -from django.test import SimpleTestCase +from django.test import SimpleTestCase, override_settings from django.utils import formats, translation from . import FormFieldAssertionsMixin @@ -156,3 +156,18 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase): f = DecimalField(max_digits=2, decimal_places=2, localize=True) localized_d = formats.localize_input(d) # -> '0,1' in French self.assertFalse(f.has_changed(d, localized_d)) + + @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',') + def test_decimalfield_support_decimal_separator(self): + f = DecimalField(localize=True) + self.assertEqual(f.clean('1001,10'), decimal.Decimal("1001.10")) + self.assertEqual(f.clean('1001.10'), decimal.Decimal("1001.10")) + + @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',', USE_THOUSAND_SEPARATOR=True, + THOUSAND_SEPARATOR='.') + def test_decimalfield_support_thousands_separator(self): + f = DecimalField(localize=True) + self.assertEqual(f.clean('1.001,10'), decimal.Decimal("1001.10")) + msg = "'Enter a number.'" + with self.assertRaisesMessage(ValidationError, msg): + f.clean('1,001.1') diff --git a/tests/forms_tests/field_tests/test_floatfield.py b/tests/forms_tests/field_tests/test_floatfield.py index 83209d7c66..b36942afa4 100644 --- a/tests/forms_tests/field_tests/test_floatfield.py +++ b/tests/forms_tests/field_tests/test_floatfield.py @@ -1,5 +1,6 @@ from django.forms import FloatField, NumberInput, ValidationError from django.test import SimpleTestCase +from django.test.utils import override_settings from django.utils import formats, translation from . import FormFieldAssertionsMixin @@ -83,3 +84,18 @@ class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase): f = FloatField(localize=True) localized_n = formats.localize_input(n) # -> '4,35' in French self.assertFalse(f.has_changed(n, localized_n)) + + @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',') + def test_decimalfield_support_decimal_separator(self): + f = FloatField(localize=True) + self.assertEqual(f.clean('1001,10'), 1001.10) + self.assertEqual(f.clean('1001.10'), 1001.10) + + @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',', USE_THOUSAND_SEPARATOR=True, + THOUSAND_SEPARATOR='.') + def test_decimalfield_support_thousands_separator(self): + f = FloatField(localize=True) + self.assertEqual(f.clean('1.001,10'), 1001.10) + msg = "'Enter a number.'" + with self.assertRaisesMessage(ValidationError, msg): + f.clean('1,001.1')