Commit cbfb8ed5 authored by Claude Paroz's avatar Claude Paroz
Browse files

Fixed a regression in forms changed_data

Thanks Loic Bistuer for spotting the regression and the initial
patch. Refs #16612.
parent 6983a1a5
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -345,8 +345,13 @@ class BaseForm(object):
                else:
                    initial_prefixed_name = self.add_initial_prefix(name)
                    hidden_widget = field.hidden_widget()
                    try:
                        initial_value = field.to_python(hidden_widget.value_from_datadict(
                            self.data, self.files, initial_prefixed_name))
                    except ValidationError:
                        # Always assume data has changed if validation fails.
                        self._changed_data.append(name)
                        continue
                if hasattr(field.widget, '_has_changed'):
                    warnings.warn("The _has_changed method on widgets is deprecated,"
                        " define it at field level instead.",
+26 −0
Original line number Diff line number Diff line
@@ -1201,6 +1201,32 @@ class FormsTestCase(TestCase):
<option value="w">whiz</option>
</select></li>""")

    def test_changed_data(self):
        class Person(Form):
            first_name = CharField(initial='Hans')
            last_name = CharField(initial='Greatel')
            birthday = DateField(initial=datetime.date(1974, 8, 16))

        p = Person(data={'first_name': 'Hans', 'last_name': 'Scrmbl',
                         'birthday': '1974-08-16'})
        self.assertTrue(p.is_valid())
        self.assertNotIn('first_name', p.changed_data)
        self.assertIn('last_name', p.changed_data)
        self.assertNotIn('birthday', p.changed_data)

        # Test that field raising ValidationError is always in changed_data
        class PedanticField(forms.Field):
            def to_python(self, value):
                raise ValidationError('Whatever')

        class Person2(Person):
            pedantic = PedanticField(initial='whatever', show_hidden_initial=True)

        p = Person2(data={'first_name': 'Hans', 'last_name': 'Scrmbl',
                         'birthday': '1974-08-16', 'initial-pedantic': 'whatever'})
        self.assertFalse(p.is_valid())
        self.assertIn('pedantic', p.changed_data)

    def test_boundfield_values(self):
        # It's possible to get to the value which would be used for rendering
        # the widget for a field by using the BoundField's value method.