mirror of https://github.com/django/django.git
Fixed #25078 -- Added support for disabled form fields
Thanks Keryn Knight and Tim Graham for the reviews.
This commit is contained in:
parent
1fed8dd715
commit
1ef4aeab40
|
@ -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
|
||||
|
@ -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):
|
||||
|
|
|
@ -386,7 +386,10 @@ 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.
|
||||
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
|
||||
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):
|
||||
initial = self.initial.get(name, field.initial)
|
||||
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
--------------------------------------
|
||||
|
|
|
@ -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
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
@ -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:
|
||||
|
|
|
@ -501,6 +501,37 @@ class FormsTestCase(SimpleTestCase):
|
|||
<option value="P" selected="selected">Paul McCartney</option>
|
||||
</select>""")
|
||||
|
||||
def test_form_with_disabled_fields(self):
|
||||
class PersonForm(Form):
|
||||
name = CharField()
|
||||
birthday = DateField(disabled=True)
|
||||
|
||||
class PersonFormFieldInitial(Form):
|
||||
name = CharField()
|
||||
birthday = DateField(disabled=True, initial=datetime.date(1974, 8, 16))
|
||||
|
||||
# Disabled fields are generally not transmitted by user agents.
|
||||
# The value from the form's initial data is used.
|
||||
f1 = PersonForm({'name': 'John Doe'}, initial={'birthday': datetime.date(1974, 8, 16)})
|
||||
f2 = PersonFormFieldInitial({'name': 'John Doe'})
|
||||
for form in (f1, f2):
|
||||
self.assertTrue(form.is_valid())
|
||||
self.assertEqual(
|
||||
form.cleaned_data,
|
||||
{'birthday': datetime.date(1974, 8, 16), 'name': 'John Doe'}
|
||||
)
|
||||
|
||||
# Values provided in the form's data are ignored.
|
||||
data = {'name': 'John Doe', 'birthday': '1984-11-10'}
|
||||
f1 = PersonForm(data, initial={'birthday': datetime.date(1974, 8, 16)})
|
||||
f2 = PersonFormFieldInitial(data)
|
||||
for form in (f1, f2):
|
||||
self.assertTrue(form.is_valid())
|
||||
self.assertEqual(
|
||||
form.cleaned_data,
|
||||
{'birthday': datetime.date(1974, 8, 16), 'name': 'John Doe'}
|
||||
)
|
||||
|
||||
def test_hidden_data(self):
|
||||
class SongForm(Form):
|
||||
name = CharField()
|
||||
|
|
Loading…
Reference in New Issue