Fixes #10427 -- Abstract the value generation of a BoundField
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14734 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
e74edb4d53
commit
d3f5f219f5
|
@ -432,20 +432,11 @@ class BoundField(StrAndUnicode):
|
||||||
else:
|
else:
|
||||||
attrs['id'] = self.html_initial_id
|
attrs['id'] = self.html_initial_id
|
||||||
|
|
||||||
if not self.form.is_bound:
|
|
||||||
data = self.form.initial.get(self.name, self.field.initial)
|
|
||||||
if callable(data):
|
|
||||||
data = data()
|
|
||||||
else:
|
|
||||||
data = self.field.bound_data(
|
|
||||||
self.data, self.form.initial.get(self.name, self.field.initial))
|
|
||||||
data = self.field.prepare_value(data)
|
|
||||||
|
|
||||||
if not only_initial:
|
if not only_initial:
|
||||||
name = self.html_name
|
name = self.html_name
|
||||||
else:
|
else:
|
||||||
name = self.html_initial_name
|
name = self.html_initial_name
|
||||||
return widget.render(name, data, attrs=attrs)
|
return widget.render(name, self.value(), attrs=attrs)
|
||||||
|
|
||||||
def as_text(self, attrs=None, **kwargs):
|
def as_text(self, attrs=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -470,6 +461,21 @@ class BoundField(StrAndUnicode):
|
||||||
return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name)
|
return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name)
|
||||||
data = property(_data)
|
data = property(_data)
|
||||||
|
|
||||||
|
def value(self):
|
||||||
|
"""
|
||||||
|
Returns the value for this BoundField, using the initial value if
|
||||||
|
the form is not bound or the data otherwise.
|
||||||
|
"""
|
||||||
|
if not self.form.is_bound:
|
||||||
|
data = self.form.initial.get(self.name, self.field.initial)
|
||||||
|
if callable(data):
|
||||||
|
data = data()
|
||||||
|
else:
|
||||||
|
data = self.field.bound_data(
|
||||||
|
self.data, self.form.initial.get(self.name, self.field.initial)
|
||||||
|
)
|
||||||
|
return self.field.prepare_value(data)
|
||||||
|
|
||||||
def label_tag(self, contents=None, attrs=None):
|
def label_tag(self, contents=None, attrs=None):
|
||||||
"""
|
"""
|
||||||
Wraps the given contents in a <label>, if the field has an ID attribute.
|
Wraps the given contents in a <label>, if the field has an ID attribute.
|
||||||
|
|
|
@ -584,36 +584,29 @@ More granular output
|
||||||
The ``as_p()``, ``as_ul()`` and ``as_table()`` methods are simply shortcuts for
|
The ``as_p()``, ``as_ul()`` and ``as_table()`` methods are simply shortcuts for
|
||||||
lazy developers -- they're not the only way a form object can be displayed.
|
lazy developers -- they're not the only way a form object can be displayed.
|
||||||
|
|
||||||
To display the HTML for a single field in your form, use dictionary lookup
|
.. class:: BoundField
|
||||||
syntax using the field's name as the key, and print the resulting object::
|
|
||||||
|
|
||||||
>>> f = ContactForm()
|
Used to display HTML or access attributes for a single field of a
|
||||||
>>> print f['subject']
|
:class:`Form` instance.
|
||||||
<input id="id_subject" type="text" name="subject" maxlength="100" />
|
|
||||||
>>> print f['message']
|
The :meth:`__unicode__` and :meth:`__str__` methods of this object displays
|
||||||
<input type="text" name="message" id="id_message" />
|
the HTML for this field.
|
||||||
>>> print f['sender']
|
|
||||||
<input type="text" name="sender" id="id_sender" />
|
|
||||||
>>> print f['cc_myself']
|
|
||||||
<input type="checkbox" name="cc_myself" id="id_cc_myself" />
|
|
||||||
|
|
||||||
Call ``str()`` or ``unicode()`` on the field to get its rendered HTML as a
|
To retrieve a single ``BoundField``, use dictionary lookup syntax on your form
|
||||||
string or Unicode object, respectively::
|
using the field's name as the key::
|
||||||
|
|
||||||
>>> str(f['subject'])
|
>>> form = ContactForm()
|
||||||
'<input id="id_subject" type="text" name="subject" maxlength="100" />'
|
>>> print form['subject']
|
||||||
>>> unicode(f['subject'])
|
<input id="id_subject" type="text" name="subject" maxlength="100" />
|
||||||
u'<input id="id_subject" type="text" name="subject" maxlength="100" />'
|
|
||||||
|
|
||||||
Form objects define a custom ``__iter__()`` method, which allows you to loop
|
To retrieve all ``BoundField`` objects, iterate the form::
|
||||||
through their fields::
|
|
||||||
|
|
||||||
>>> f = ContactForm()
|
>>> form = ContactForm()
|
||||||
>>> for field in f: print field
|
>>> for boundfield in form: print boundfield
|
||||||
<input id="id_subject" type="text" name="subject" maxlength="100" />
|
<input id="id_subject" type="text" name="subject" maxlength="100" />
|
||||||
<input type="text" name="message" id="id_message" />
|
<input type="text" name="message" id="id_message" />
|
||||||
<input type="text" name="sender" id="id_sender" />
|
<input type="text" name="sender" id="id_sender" />
|
||||||
<input type="checkbox" name="cc_myself" id="id_cc_myself" />
|
<input type="checkbox" name="cc_myself" id="id_cc_myself" />
|
||||||
|
|
||||||
The field-specific output honors the form object's ``auto_id`` setting::
|
The field-specific output honors the form object's ``auto_id`` setting::
|
||||||
|
|
||||||
|
@ -624,26 +617,31 @@ The field-specific output honors the form object's ``auto_id`` setting::
|
||||||
>>> print f['message']
|
>>> print f['message']
|
||||||
<input type="text" name="message" id="id_message" />
|
<input type="text" name="message" id="id_message" />
|
||||||
|
|
||||||
For a field's list of errors, access the field's ``errors`` attribute. This
|
For a field's list of errors, access the field's ``errors`` attribute.
|
||||||
is a list-like object that is displayed as an HTML ``<ul class="errorlist">``
|
|
||||||
when printed::
|
|
||||||
|
|
||||||
>>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
|
.. attribute:: BoundField.errors
|
||||||
>>> f = ContactForm(data, auto_id=False)
|
|
||||||
>>> print f['message']
|
|
||||||
<input type="text" name="message" />
|
|
||||||
>>> f['message'].errors
|
|
||||||
[u'This field is required.']
|
|
||||||
>>> print f['message'].errors
|
|
||||||
<ul class="errorlist"><li>This field is required.</li></ul>
|
|
||||||
>>> f['subject'].errors
|
|
||||||
[]
|
|
||||||
>>> print f['subject'].errors
|
|
||||||
|
|
||||||
>>> str(f['subject'].errors)
|
A list-like object that is displayed as an HTML ``<ul class="errorlist">``
|
||||||
''
|
when printed::
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
>>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
|
||||||
|
>>> f = ContactForm(data, auto_id=False)
|
||||||
|
>>> print f['message']
|
||||||
|
<input type="text" name="message" />
|
||||||
|
>>> f['message'].errors
|
||||||
|
[u'This field is required.']
|
||||||
|
>>> print f['message'].errors
|
||||||
|
<ul class="errorlist"><li>This field is required.</li></ul>
|
||||||
|
>>> f['subject'].errors
|
||||||
|
[]
|
||||||
|
>>> print f['subject'].errors
|
||||||
|
|
||||||
|
>>> str(f['subject'].errors)
|
||||||
|
''
|
||||||
|
|
||||||
|
.. method:: BoundField.css_classes()
|
||||||
|
|
||||||
|
.. versionadded:: 1.2
|
||||||
|
|
||||||
When you use Django's rendering shortcuts, CSS classes are used to
|
When you use Django's rendering shortcuts, CSS classes are used to
|
||||||
indicate required form fields or fields that contain errors. If you're
|
indicate required form fields or fields that contain errors. If you're
|
||||||
|
@ -662,6 +660,21 @@ those classes as an argument::
|
||||||
>>> f['message'].css_classes('foo bar')
|
>>> f['message'].css_classes('foo bar')
|
||||||
'foo bar required'
|
'foo bar required'
|
||||||
|
|
||||||
|
.. method:: BoundField.values()
|
||||||
|
|
||||||
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
Use this method to render the raw value of this field as it would be rendered
|
||||||
|
by a ``Widget``::
|
||||||
|
|
||||||
|
>>> initial = {'subject': 'welcome'}
|
||||||
|
>>> unbound_form = ContactForm(initial=initial)
|
||||||
|
>>> bound_form = ContactForm(data, initial=initial)
|
||||||
|
>>> print unbound_form['subject'].value
|
||||||
|
welcome
|
||||||
|
>>> print bound_form['subject'].value
|
||||||
|
hi
|
||||||
|
|
||||||
.. _binding-uploaded-files:
|
.. _binding-uploaded-files:
|
||||||
|
|
||||||
Binding uploaded files to a form
|
Binding uploaded files to a form
|
||||||
|
|
|
@ -1151,6 +1151,21 @@ class FormsTestCase(TestCase):
|
||||||
<option value="w">whiz</option>
|
<option value="w">whiz</option>
|
||||||
</select></li>""")
|
</select></li>""")
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
class UserRegistration(Form):
|
||||||
|
username = CharField(max_length=10, initial='djangonaut')
|
||||||
|
password = CharField(widget=PasswordInput)
|
||||||
|
|
||||||
|
unbound = UserRegistration()
|
||||||
|
bound = UserRegistration({'password': 'foo'})
|
||||||
|
self.assertEqual(bound['username'].value(), None)
|
||||||
|
self.assertEqual(unbound['username'].value(), 'djangonaut')
|
||||||
|
self.assertEqual(bound['password'].value(), 'foo')
|
||||||
|
self.assertEqual(unbound['password'].value(), None)
|
||||||
|
|
||||||
def test_help_text(self):
|
def test_help_text(self):
|
||||||
# You can specify descriptive text for a field by using the 'help_text' argument)
|
# You can specify descriptive text for a field by using the 'help_text' argument)
|
||||||
class UserRegistration(Form):
|
class UserRegistration(Form):
|
||||||
|
|
Loading…
Reference in New Issue