Commit d3f5f219 authored by Chris Beaven's avatar Chris Beaven
Browse files

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
parent e74edb4d
Loading
Loading
Loading
Loading
+16 −10
Original line number Diff line number Diff line
@@ -432,20 +432,11 @@ class BoundField(StrAndUnicode):
            else:
                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:
            name = self.html_name
        else:
            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):
        """
@@ -470,6 +461,21 @@ class BoundField(StrAndUnicode):
        return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name)
    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):
        """
        Wraps the given contents in a <label>, if the field has an ID attribute.
+55 −42
Original line number Diff line number Diff line
@@ -584,32 +584,25 @@ More granular output
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.

To display the HTML for a single field in your form, use dictionary lookup
syntax using the field's name as the key, and print the resulting object::
.. class:: BoundField

    >>> f = ContactForm()
    >>> print f['subject']
    <input id="id_subject" type="text" name="subject" maxlength="100" />
    >>> print f['message']
    <input type="text" name="message" id="id_message" />
    >>> 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" />
   Used to display HTML or access attributes for a single field of a
   :class:`Form` instance.
   
Call ``str()`` or ``unicode()`` on the field to get its rendered HTML as a
string or Unicode object, respectively::
   The :meth:`__unicode__` and :meth:`__str__` methods of this object displays
   the HTML for this field.

    >>> str(f['subject'])
    '<input id="id_subject" type="text" name="subject" maxlength="100" />'
    >>> unicode(f['subject'])
    u'<input id="id_subject" type="text" name="subject" maxlength="100" />'
To retrieve a single ``BoundField``, use dictionary lookup syntax on your form
using the field's name as the key::

Form objects define a custom ``__iter__()`` method, which allows you to loop
through their fields::
	>>> form = ContactForm()
	>>> print form['subject']
	<input id="id_subject" type="text" name="subject" maxlength="100" />

    >>> f = ContactForm()
    >>> for field in f: print field
To retrieve all ``BoundField`` objects, iterate the form::

	>>> form = ContactForm()
	>>> for boundfield in form: print boundfield
	<input id="id_subject" type="text" name="subject" maxlength="100" />
	<input type="text" name="message" id="id_message" />
	<input type="text" name="sender" id="id_sender" />
@@ -624,8 +617,11 @@ The field-specific output honors the form object's ``auto_id`` setting::
    >>> print f['message']
    <input type="text" name="message" id="id_message" />

For a field's list of errors, access the field's ``errors`` attribute. This
is a list-like object that is displayed as an HTML ``<ul class="errorlist">``
For a field's list of errors, access the field's ``errors`` attribute.

.. attribute:: BoundField.errors

    A list-like object that is displayed as an HTML ``<ul class="errorlist">``
    when printed::

        >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
@@ -643,6 +639,8 @@ when printed::
        >>> str(f['subject'].errors)
	    ''

.. method:: BoundField.css_classes()

   .. versionadded:: 1.2

When you use Django's rendering shortcuts, CSS classes are used to
@@ -662,6 +660,21 @@ those classes as an argument::
	>>> f['message'].css_classes('foo bar')
	'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 to a form
+15 −0
Original line number Diff line number Diff line
@@ -1151,6 +1151,21 @@ class FormsTestCase(TestCase):
<option value="w">whiz</option>
</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):
        # You can specify descriptive text for a field by using the 'help_text' argument)
        class UserRegistration(Form):