Code

Ticket #20765: 0001-Fixed-20765-Use-exponential-form-to-set-step-attribu.patch

File 0001-Fixed-20765-Use-exponential-form-to-set-step-attribu.patch, 2.5 KB (added by charettes, 9 months ago)
  • django/forms/fields.py

    From dcb42cd13752fe2d583652e48ac97ea6e48d8d56 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 -- Use exponential form to set `step` attribute
     on `NumberInput`.
    
    Browsers 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                 |  8 ++++++--
     tests/forms_tests/tests/test_fields.py | 11 +++++++++++
     2 files changed, 17 insertions(+), 2 deletions(-)
    
    diff --git a/django/forms/fields.py b/django/forms/fields.py
    index c4bc3fa8..1edf10a 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            if self.decimal_places is not None: 
     375                step = str(Decimal('1') / 10 ** self.decimal_places).lower() 
     376            else: 
     377                step = 'any' 
     378            attrs.setdefault('step', step) 
    375379        return attrs 
    376380 
    377381 
  • 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..dab67b4 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_decimalfield_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=10, decimal_places=0) 
     382        self.assertEqual(f.widget_attrs(NumberInput()), {'step': '1'}) 
     383        f = DecimalField(max_digits=19, decimal_places=19) 
     384        self.assertEqual(f.widget_attrs(NumberInput()), {'step': '1e-19'}) 
     385        f = DecimalField(max_digits=20) 
     386        self.assertEqual(f.widget_attrs(NumberInput()), {'step': 'any'}) 
     387 
    377388    def test_decimalfield_localized(self): 
    378389        """ 
    379390        Make sure localized DecimalField's widget renders to a text input with