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 Simon Charette, 11 years 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
Back to Top