Commit 2f53d342 authored by Moritz Sichert's avatar Moritz Sichert Committed by Tim Graham
Browse files

Fixed #12856 -- Documented BoundField API.

parent 534aaf56
Loading
Loading
Loading
Loading
+150 −75
Original line number Diff line number Diff line
@@ -767,6 +767,8 @@ method you're using::
    <p>Sender: <input type="email" name="sender" value="invalid email address" /></p>
    <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>

.. _ref-forms-error-list-format:

Customizing the error list format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

@@ -792,10 +794,10 @@ Python 2)::
    <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>

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.
The ``as_p()``, ``as_ul()``, and ``as_table()`` methods are simply shortcuts --
they're not the only way a form object can be displayed.

.. class:: BoundField

@@ -830,12 +832,26 @@ 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.
Attributes of ``BoundField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. attribute:: BoundField.data

    This property returns the data for this :class:`~django.forms.BoundField`
    extracted by the widget's :meth:`~django.forms.Widget.value_from_datadict`
    method, or ``None`` if it wasn't given::

        >>> unbound_form = ContactForm()
        >>> print(unbound_form['subject'].data)
        None
        >>> bound_form = ContactForm(data={'subject': 'My Subject'})
        >>> print(bound_form['subject'].data)
        My Subject

.. attribute:: BoundField.errors

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

        >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
        >>> f = ContactForm(data, auto_id=False)
@@ -852,30 +868,87 @@ when printed::
        >>> str(f['subject'].errors)
        ''

.. method:: BoundField.label_tag(contents=None, attrs=None, label_suffix=None)
.. attribute:: BoundField.field

To separately render the label tag of a form field, you can call its
``label_tag`` method::
    The form :class:`~django.forms.Field` instance from the form class that
    this :class:`~django.forms.BoundField` wraps.

    >>> f = ContactForm(data)
    >>> print(f['message'].label_tag())
    <label for="id_message">Message:</label>
.. attribute:: BoundField.form

Optionally, you can provide the ``contents`` parameter which will replace the
auto-generated label tag. An optional ``attrs`` dictionary may contain
additional attributes for the ``<label>`` tag.
    The :class:`~django.forms.Form` instance this :class:`~django.forms.BoundField`
    is bound to.

The HTML that's generated includes the form's
:attr:`~django.forms.Form.label_suffix` (a colon, by default) or, if set, the
current field's :attr:`~django.forms.Field.label_suffix`. The optional
``label_suffix`` parameter allows you to override any previously set
suffix. For example, you can use an empty string to hide the label on selected
fields. If you need to do this in a template, you could write a custom
filter to allow passing parameters to ``label_tag``.
.. attribute:: BoundField.help_text

.. versionchanged:: 1.8
    The :attr:`~django.forms.Field.help_text` of the field.

    The label includes :attr:`~Form.required_css_class` if applicable.
.. attribute:: BoundField.html_name

    The name that will be used in the widget's HTML ``name`` attribute. It takes
    the form :attr:`~django.forms.Form.prefix` into account.

.. attribute:: BoundField.id_for_label

    Use this property to render the ID of this field. For example, if you are
    manually constructing a ``<label>`` in your template (despite the fact that
    :meth:`~BoundField.label_tag` will do this for you):

    .. code-block:: html+django

        <label for="{{ form.my_field.id_for_label }}">...</label>{{ my_field }}

    By default, this will be the field's name prefixed by ``id_``
    ("``id_my_field``" for the example above). You may modify the ID by setting
    :attr:`~django.forms.Widget.attrs` on the field's widget. For example,
    declaring a field like this::

        my_field = forms.CharField(widget=forms.TextInput(attrs={'id': 'myFIELD'}))

    and using the template above, would render something like:

    .. code-block:: html

        <label for="myFIELD">...</label><input id="myFIELD" type="text" name="my_field" />

.. attribute:: BoundField.is_hidden

    Returns ``True`` if this :class:`~django.forms.BoundField`'s widget is
    hidden.

.. attribute:: BoundField.label

    The :attr:`~django.forms.Field.label` of the field. This is used in
    :meth:`~BoundField.label_tag`.

.. attribute:: BoundField.name

    The name of this field in the form::

        >>> f = ContactForm()
        >>> print(f['subject'].name)
        subject
        >>> print(f['message'].name)
        message

Methods of ``BoundField``
~~~~~~~~~~~~~~~~~~~~~~~~~

.. method:: BoundField.as_hidden(attrs=None, **kwargs)

    Returns a string of HTML for representing this as an ``<input type="hidden">``.

    ``**kwargs`` are passed to :meth:`~django.forms.BoundField.as_widget`.

    This method is primarily used internally. You should use a widget instead.

.. method:: BoundField.as_widget(widget=None, attrs=None, only_initial=False)

    Renders the field by rendering the passed widget, adding any HTML
    attributes passed as ``attrs``.  If no widget is specified, then the
    field's default widget will be used.

    ``only_initial`` is used by Django internals and should not be set
    explicitly.

.. method:: BoundField.css_classes()

@@ -884,7 +957,7 @@ indicate required form fields or fields that contain errors. If you're
    manually rendering a form, you can access these CSS classes using the
    ``css_classes`` method::

    >>> f = ContactForm(data)
        >>> f = ContactForm(data={'message': ''})
        >>> f['message'].css_classes()
        'required'

@@ -892,10 +965,35 @@ If you want to provide some additional classes in addition to the
    error and required classes that may be required, you can provide
    those classes as an argument::

    >>> f = ContactForm(data)
        >>> f = ContactForm(data={'message': ''})
        >>> f['message'].css_classes('foo bar')
        'foo bar required'

.. method:: BoundField.label_tag(contents=None, attrs=None, label_suffix=None)

    To separately render the label tag of a form field, you can call its
    ``label_tag()`` method::

        >>> f = ContactForm(data={'message': ''})
        >>> print(f['message'].label_tag())
        <label for="id_message">Message:</label>

    You can provide the ``contents`` parameter which will replace the
    auto-generated label tag. An ``attrs`` dictionary may contain additional
    attributes for the ``<label>`` tag.

    The HTML that's generated includes the form's
    :attr:`~django.forms.Form.label_suffix` (a colon, by default) or, if set, the
    current field's :attr:`~django.forms.Field.label_suffix`. The optional
    ``label_suffix`` parameter allows you to override any previously set
    suffix. For example, you can use an empty string to hide the label on selected
    fields. If you need to do this in a template, you could write a custom
    filter to allow passing parameters to ``label_tag``.

    .. versionchanged:: 1.8

        The label includes :attr:`~Form.required_css_class` if applicable.

.. method:: BoundField.value()

    Use this method to render the raw value of this field as it would be rendered
@@ -903,35 +1001,12 @@ by a ``Widget``::

        >>> initial = {'subject': 'welcome'}
        >>> unbound_form = ContactForm(initial=initial)
    >>> bound_form = ContactForm(data, initial=initial)
        >>> bound_form = ContactForm(data={'subject': 'hi'}, initial=initial)
        >>> print(unbound_form['subject'].value())
        welcome
        >>> print(bound_form['subject'].value())
        hi

.. attribute:: BoundField.id_for_label

Use this property to render the ID of this field. For example, if you are
manually constructing a ``<label>`` in your template (despite the fact that
:meth:`~BoundField.label_tag` will do this for you):

.. code-block:: html+django

    <label for="{{ form.my_field.id_for_label }}">...</label>{{ my_field }}

By default, this will be the field's name prefixed by ``id_``
("``id_my_field``" for the example above). You may modify the ID by setting
:attr:`~django.forms.Widget.attrs` on the field's widget. For example,
declaring a field like this::

    my_field = forms.CharField(widget=forms.TextInput(attrs={'id': 'myFIELD'}))

and using the template above, would render something like:

.. code-block:: html

    <label for="myFIELD">...</label><input id="myFIELD" type="text" name="my_field" />

Customizing ``BoundField``
--------------------------

+10 −0
Original line number Diff line number Diff line
@@ -230,6 +230,16 @@ foundation for custom widgets.
           In older versions, this attribute was only defined on the date
           and time widgets (as ``False``).

    .. method:: id_for_label(self, id_)

        Returns the HTML ID attribute of this widget for use by a ``<label>``,
        given the ID of the field. Returns ``None`` if an ID isn't available.

        This hook is necessary because some widgets have multiple HTML
        elements and, thus, multiple IDs. In that case, this method should
        return an ID value that corresponds to the first ID in the widget's
        tags.

    .. method:: render(name, value, attrs=None)

        Returns HTML for the widget, as a Unicode string. This method must be
+5 −0
Original line number Diff line number Diff line
@@ -690,6 +690,11 @@ Useful attributes on ``{{ field }}`` include:
    :class:`~django.forms.Field` attributes, e.g.
    ``{{ char_field.field.max_length }}``.

.. seealso::

    For a complete list of attributes and methods, see
    :class:`~django.forms.BoundField`.

Looping over hidden and visible fields
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^