Code

Ticket #20765: 0001-Fixed-20765-Avoid-setting-step-on-NumberInput-when-m.patch

File 0001-Fixed-20765-Avoid-setting-step-on-NumberInput-when-m.patch, 2.4 KB (added by charettes, 9 months ago)
  • django/forms/fields.py

    From 7aec160e44a0a32bcec661b838dff625bd045531 Mon Sep 17 00:00:00 2001
    From: Simon Charette <charette.s@gmail.com>
    Date: Thu, 18 Jul 2013 22:01:51 -0400
    Subject: [PATCH] Fixed #20765 -- Avoid setting `step` on `NumberInput` when
     `max_digits` > 18.
    
    Browser parse 10^-18 as 0 which is an invalid value for this attribute.
    
    Thanks to Trac alias matklad for the report.
    ---
     django/forms/fields.py                 | 9 +++++++--
     tests/forms_tests/tests/test_fields.py | 9 +++++++++
     2 files changed, 16 insertions(+), 2 deletions(-)
    
    diff --git a/django/forms/fields.py b/django/forms/fields.py
    index c4bc3fa8..1f7a5f2 100644
    a b class DecimalField(IntegerField): 
    370370 
    371371    def widget_attrs(self, widget): 
    372372        attrs = super(DecimalField, self).widget_attrs(widget) 
    373         if isinstance(widget, NumberInput) and self.decimal_places: 
    374             attrs['step'] = '0.%s1' % ('0' * (self.decimal_places - 1)) 
     373        if isinstance(widget, NumberInput): 
     374            # `step` < 10^-18 is parsed as 0. ref #20765 
     375            if self.decimal_places and self.decimal_places <= 18: 
     376                step = "0.%s1" % ('0' * (self.decimal_places - 1)) 
     377            else: 
     378                step = 'any' 
     379            attrs.setdefault('step', step) 
    375380        return attrs 
    376381 
    377382 
  • tests/forms_tests/tests/test_fields.py

    diff --git a/tests/forms_tests/tests/test_fields.py b/tests/forms_tests/tests/test_fields.py
    index f7d8350..eb28462 100644
    a b class FieldsTests(SimpleTestCase): 
    374374        self.assertEqual(f.clean('.01'), Decimal(".01")) 
    375375        self.assertRaisesMessage(ValidationError, "'Ensure that there are no more than 0 digits before the decimal point.'", f.clean, '1.1') 
    376376 
     377    def test_decimal_field_widget_attrs(self): 
     378        f = DecimalField(max_digits=6, decimal_places=2) 
     379        self.assertEqual(f.widget_attrs(Widget()), {}) 
     380        self.assertEqual(f.widget_attrs(NumberInput()), {'step': '0.01'}) 
     381        f = DecimalField(max_digits=19, decimal_places=19) 
     382        self.assertEqual(f.widget_attrs(NumberInput()), {'step': 'any'}) 
     383        f = DecimalField(max_digits=20) 
     384        self.assertEqual(f.widget_attrs(NumberInput()), {'step': 'any'}) 
     385 
    377386    def test_decimalfield_localized(self): 
    378387        """ 
    379388        Make sure localized DecimalField's widget renders to a text input with