Loading django/forms/fields.py +4 −1 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ class Field(six.with_metaclass(RenameFieldMethods, object)): def __init__(self, required=True, widget=None, label=None, initial=None, help_text='', error_messages=None, show_hidden_initial=False, validators=[], localize=False, label_suffix=None): validators=[], localize=False, disabled=False, label_suffix=None): # required -- Boolean that specifies whether the field is required. # True by default. # widget -- A Widget class, or instance of a Widget class, that should Loading @@ -90,11 +90,14 @@ class Field(six.with_metaclass(RenameFieldMethods, object)): # hidden widget with initial value after widget. # validators -- List of additional validators to use # localize -- Boolean that specifies if the field should be localized. # disabled -- Boolean that specifies whether the field is disabled, that # is its widget is shown in the form but not editable. # label_suffix -- Suffix to be added to the label. Overrides # form's label_suffix. self.required, self.label, self.initial = required, label, initial self.show_hidden_initial = show_hidden_initial self.help_text = help_text self.disabled = disabled self.label_suffix = label_suffix widget = widget or self.widget if isinstance(widget, type): Loading django/forms/forms.py +6 −1 Original line number Diff line number Diff line Loading @@ -386,6 +386,9 @@ class BaseForm(object): # value_from_datadict() gets the data from the data dictionaries. # Each widget type knows how to retrieve its own data, because some # widgets split data over several HTML fields. if field.disabled: value = self.initial.get(name, field.initial) else: value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) try: if isinstance(field, FileField): Loading Loading @@ -567,6 +570,8 @@ class BoundField(object): widget.is_localized = True attrs = attrs or {} if self.field.disabled: attrs['disabled'] = True auto_id = self.auto_id if auto_id and 'id' not in attrs and 'id' not in widget.attrs: if not only_initial: Loading docs/ref/forms/fields.txt +11 −0 Original line number Diff line number Diff line Loading @@ -299,6 +299,17 @@ as the rendered output. See the :ref:`format localization <format-localization>` documentation for more information. ``disabled`` ~~~~~~~~~~~~ .. attribute:: Field.disabled .. versionadded:: 1.9 The ``disabled`` boolean argument, when set to ``True``, disables a form field using the ``disabled`` HTML attribute so that it won't be editable by users. Even if a user tampers with the field's value submitted to the server, it will be ignored in favor of the value from the form's initial data. Checking if the field data has changed -------------------------------------- Loading docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -313,6 +313,9 @@ Forms and trailing whitespace. As this defaults to ``True`` this is different behavior from previous releases. * Form fields now support the :attr:`~django.forms.Field.disabled` argument, allowing the field widget to be displayed disabled by browsers. Generic Views ^^^^^^^^^^^^^ Loading tests/forms_tests/tests/test_fields.py +10 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,10 @@ class FieldsTests(SimpleTestCase): self.assertEqual(f.clean(' 1'), ' 1') self.assertEqual(f.clean('1 '), '1 ') def test_charfield_disabled(self): f = CharField(disabled=True) self.assertWidgetRendersTo(f, '<input type="text" name="f" id="id_f" disabled />') # IntegerField ################################################################ def test_integerfield_1(self): Loading Loading @@ -1076,6 +1080,12 @@ class FieldsTests(SimpleTestCase): form = ChoiceFieldForm() self.assertEqual([('P', 'Paul')], list(form.fields['choicefield'].choices)) def test_choicefield_disabled(self): f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')], disabled=True) self.assertWidgetRendersTo(f, '<select id="id_f" name="f" disabled><option value="J">John</option>' '<option value="P">Paul</option></select>') # TypedChoiceField ############################################################ # TypedChoiceField is just like ChoiceField, except that coerced types will # be returned: Loading Loading
django/forms/fields.py +4 −1 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ class Field(six.with_metaclass(RenameFieldMethods, object)): def __init__(self, required=True, widget=None, label=None, initial=None, help_text='', error_messages=None, show_hidden_initial=False, validators=[], localize=False, label_suffix=None): validators=[], localize=False, disabled=False, label_suffix=None): # required -- Boolean that specifies whether the field is required. # True by default. # widget -- A Widget class, or instance of a Widget class, that should Loading @@ -90,11 +90,14 @@ class Field(six.with_metaclass(RenameFieldMethods, object)): # hidden widget with initial value after widget. # validators -- List of additional validators to use # localize -- Boolean that specifies if the field should be localized. # disabled -- Boolean that specifies whether the field is disabled, that # is its widget is shown in the form but not editable. # label_suffix -- Suffix to be added to the label. Overrides # form's label_suffix. self.required, self.label, self.initial = required, label, initial self.show_hidden_initial = show_hidden_initial self.help_text = help_text self.disabled = disabled self.label_suffix = label_suffix widget = widget or self.widget if isinstance(widget, type): Loading
django/forms/forms.py +6 −1 Original line number Diff line number Diff line Loading @@ -386,6 +386,9 @@ class BaseForm(object): # value_from_datadict() gets the data from the data dictionaries. # Each widget type knows how to retrieve its own data, because some # widgets split data over several HTML fields. if field.disabled: value = self.initial.get(name, field.initial) else: value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) try: if isinstance(field, FileField): Loading Loading @@ -567,6 +570,8 @@ class BoundField(object): widget.is_localized = True attrs = attrs or {} if self.field.disabled: attrs['disabled'] = True auto_id = self.auto_id if auto_id and 'id' not in attrs and 'id' not in widget.attrs: if not only_initial: Loading
docs/ref/forms/fields.txt +11 −0 Original line number Diff line number Diff line Loading @@ -299,6 +299,17 @@ as the rendered output. See the :ref:`format localization <format-localization>` documentation for more information. ``disabled`` ~~~~~~~~~~~~ .. attribute:: Field.disabled .. versionadded:: 1.9 The ``disabled`` boolean argument, when set to ``True``, disables a form field using the ``disabled`` HTML attribute so that it won't be editable by users. Even if a user tampers with the field's value submitted to the server, it will be ignored in favor of the value from the form's initial data. Checking if the field data has changed -------------------------------------- Loading
docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -313,6 +313,9 @@ Forms and trailing whitespace. As this defaults to ``True`` this is different behavior from previous releases. * Form fields now support the :attr:`~django.forms.Field.disabled` argument, allowing the field widget to be displayed disabled by browsers. Generic Views ^^^^^^^^^^^^^ Loading
tests/forms_tests/tests/test_fields.py +10 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,10 @@ class FieldsTests(SimpleTestCase): self.assertEqual(f.clean(' 1'), ' 1') self.assertEqual(f.clean('1 '), '1 ') def test_charfield_disabled(self): f = CharField(disabled=True) self.assertWidgetRendersTo(f, '<input type="text" name="f" id="id_f" disabled />') # IntegerField ################################################################ def test_integerfield_1(self): Loading Loading @@ -1076,6 +1080,12 @@ class FieldsTests(SimpleTestCase): form = ChoiceFieldForm() self.assertEqual([('P', 'Paul')], list(form.fields['choicefield'].choices)) def test_choicefield_disabled(self): f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')], disabled=True) self.assertWidgetRendersTo(f, '<select id="id_f" name="f" disabled><option value="J">John</option>' '<option value="P">Paul</option></select>') # TypedChoiceField ############################################################ # TypedChoiceField is just like ChoiceField, except that coerced types will # be returned: Loading