Ticket #16264: django-16264.5.diff

File django-16264.5.diff, 18.2 KB (added by julien, 4 years ago)
  • docs/ref/forms/fields.txt

    diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt
    index 3fc5b8a..66c05e5 100644
    a b as the rendered output. 
    278278See the :ref:`format localization <format-localization>` documentation for
    279279more information.
    280280
     281.. _built-in fields:
    281282
    282283Built-in ``Field`` classes
    283284--------------------------
  • docs/ref/forms/widgets.txt

    diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt
    index dbdf109..13c0c88 100644
    a b A widget is Django's representation of a HTML input element. The widget 
    1111handles the rendering of the HTML, and the extraction of data from a GET/POST
    1212dictionary that corresponds to the widget.
    1313
     14Specifying widgets
     15------------------
     16
     17Whenever you specify a field on a form, Django will use a default widget
     18that is appropriate to the type of data that is to be displayed. To find
     19which widget is used on which field, see the documentation about
     20:ref:`built-in fields`.
     21
     22However, if you want to use a different widget for a field, you can
     23just use the :attr:`~Field.widget` argument on the field definition. For
     24example:
     25
     26    .. code-block:: python
     27
     28        from django import forms
     29
     30        class CommentForm(forms.Form):
     31            name = forms.CharField()
     32            url = forms.URLField()
     33            comment = forms.CharField(widget=forms.Textarea)
     34
     35This would specify a form with a comment that uses a larger :class:`Textarea`
     36widget, rather than the default :class:`TextInput` widget.
     37
     38
     39Setting arguments for widgets
     40-----------------------------
     41
     42Many widgets have optional extra arguments; they can be set when defining the
     43widget on the field. In the following example, the
     44:attr:`~SelectDateWidget.years` attribute is set for a
     45:class:`~django.forms.widgets.extras.SelectDateWidget`:
     46
     47    .. code-block:: python
     48
     49        from django.forms.fields import DateField, ChoiceField, MultipleChoiceField
     50        from django.forms.widgets import RadioSelect, CheckboxSelectMultiple
     51        from django.forms.widgets.extras import SelectDateWidget
     52
     53        BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
     54        GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'))
     55        FAVOURITE_COLORS_CHOICES = (('blue', 'Blue'),
     56                                    ('green', 'Green'),
     57                                    ('black', 'Black'))
     58
     59        class SimpleForm(forms.Form):
     60            birth_year = DateField(widget=SelectDateWidget(years=YEAR_CHOICES))
     61            gender = ChoiceField(widget=RadioSelect, choices=RADIO_CHOICES)
     62            favourite_colors = forms.MultipleChoiceField(required=False,
     63                widget=CheckboxSelectMultiple, choices=CHECKBOX_CHOICES)
     64
     65See the :ref:`built-in widgets` for more information about which widgets
     66are available and which arguments they accept.
     67
     68
     69Widgets inheriting from the Select widget
     70-----------------------------------------
     71
     72Widgets inheriting from the :class:`Select` widget deal with choices. They
     73present the user with a list of options to choose from. The different widgets
     74present this choice differently; the :class:`Select` widget itself uses a
     75``<select>`` HTML list representation, while :class:`RadioSelect` uses radio
     76buttons.
     77
     78:class:`Select` widgets are used by default on :class:`ChoiceField` fields. The
     79choices displayed on the widget are inherited from the :class:`ChoiceField` and
     80changing :attr:`ChoiceField.choices` will update :attr:`Select.choices`. For
     81example:
     82
     83    .. code-block:: python
     84
     85        >>> from django import forms
     86        >>> CHOICES = (('1', 'First',), ('2', 'Second',)))
     87        >>> choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
     88        >>> choice_field.choices
     89        [('1', 'First'), ('2', 'Second')]
     90        >>> choice_field.widget.choices
     91        [('1', 'First'), ('2', 'Second')]
     92        >>> choice_field.widget.choices = ()
     93        >>> choice_field.choices = (('1', 'First and only',),)
     94        >>> choice_field.widget.choices
     95        [('1', 'First and only')]
     96
     97
     98Widgets which offer a :attr:`~Select.choices` attribute can however be used
     99with fields which are not based on choice -- such as a :class:`CharField` --
     100but it is recommended to use a :class:`ChoiceField`-based field when the
     101choices are inherent to the model and not just the representational widget.
     102
     103Customizing widget instances
     104----------------------------
     105
     106When Django renders a widget as HTML, it only renders the bare minimum
     107HTML - Django doesn't add a class definition, or any other widget-specific
     108attributes. This means that all :class:`TextInput` widgets will appear the same
     109on your Web page.
     110
     111If you want to make one widget look different to another, you need to
     112specify additional attributes for each widget. When you specify a
     113widget, you can provide a list of attributes that will be added to the
     114rendered HTML for the widget.
     115
     116For example, take the following simple form:
     117
     118    .. code-block:: python
     119
     120        from django import forms
     121
     122        class CommentForm(forms.Form):
     123            name = forms.CharField()
     124            url = forms.URLField()
     125            comment = forms.CharField()
     126
     127This form will include three default :class:`TextInput` widgets, with default
     128rendering -- no CSS class, no extra attributes. This means that the input boxes
     129provided for each widget will be rendered exactly the same:
     130
     131    .. code-block:: python
     132
     133        >>> f = CommentForm(auto_id=False)
     134        >>> f.as_table()
     135        <tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
     136        <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
     137        <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
     138
     139
     140On a real Web page, you probably don't want every widget to look the same. You
     141might want a larger input element for the comment, and you might want the
     142'name' widget to have some special CSS class. To do this, you use the
     143:attr:`Widget.attrs` argument when creating the widget:
     144
     145For example:
     146
     147    .. code-block:: python
     148
     149        class CommentForm(forms.Form):
     150            name = forms.CharField(
     151                        widget=forms.TextInput(attrs={'class':'special'}))
     152            url = forms.URLField()
     153            comment = forms.CharField(
     154                       widget=forms.TextInput(attrs={'size':'40'}))
     155
     156Django will then include the extra attributes in the rendered output:
     157
     158    .. code-block:: python
     159
     160        >>> f = CommentForm(auto_id=False)
     161        >>> f.as_table()
     162        <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
     163        <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
     164        <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
     165
     166.. _built-in widgets:
     167
     168Built-in widgets
     169----------------
     170
    14171Django provides a representation of all the basic HTML widgets, plus some
    15172commonly used groups of widgets:
    16173
     174.. class:: Widget
     175
     176    This abstract class cannot be rendered, but provides the basic attribute :attr:`~Widget.attrs`.
     177
     178    .. attribute:: Widget.attrs
     179
     180        A dictionary containing HTML attributes to be set on the rendered widget.
     181
     182        .. code-block:: python
     183
     184            >>> name = forms.TextInput(attrs={'size': 10, 'title': 'Your name',})
     185            >>> name.render('name', 'A name')
     186            u'<input title="Your name" type="text" name="name" value="A name" size="10" />'
     187
     188
    17189.. class:: TextInput
    18190
    19191    Text input: ``<input type='text' ...>``
    commonly used groups of widgets: 
    29201        Determines whether the widget will have a value filled in when the
    30202        form is re-displayed after a validation error (default is ``False``).
    31203
    32 .. versionchanged:: 1.3
    33     The default value for
    34     :attr:`~PasswordInput.render_value` was
    35     changed from ``True`` to ``False``
     204        .. versionchanged:: 1.3
     205            The default value for
     206            :attr:`~PasswordInput.render_value` was
     207            changed from ``True`` to ``False``
    36208
    37209.. class:: HiddenInput
    38210
    commonly used groups of widgets: 
    42214
    43215    Multiple ``<input type='hidden' ...>`` widgets.
    44216
     217    A widget that handles multiple hidden widgets for fields that have a list
     218    of values.
     219
     220    .. attribute:: MultipleHiddenInput.choices
     221
     222        This attribute is optional when the field does not have a
     223        :attr:`~Field.choices` attribute. If it does, it will override anything
     224        you set here when the attribute is updated on the :class:`Field`.
     225
    45226.. class:: FileInput
    46227
    47228    File upload input: ``<input type='file' ...>``
    commonly used groups of widgets: 
    64245
    65246        The format in which this field's initial value will be displayed.
    66247
    67     If no ``format`` argument is provided, the default format is ``'%Y-%m-%d'``.
     248    If no ``format`` argument is provided, the default format is the first
     249    format found in :setting:`DATE_INPUT_FORMATS` and respects
     250    :ref:`format-localization`.
    68251
    69252.. class:: DateTimeInput
    70253
    commonly used groups of widgets: 
    76259
    77260        The format in which this field's initial value will be displayed.
    78261
    79     If no ``format`` argument is provided, the default format is ``'%Y-%m-%d
    80     %H:%M:%S'``.
     262    If no ``format`` argument is provided, the default format is the first
     263    format found in :setting:`DATETIME_INPUT_FORMATS` and respects
     264    :ref:`format-localization`.
    81265
    82266.. class:: TimeInput
    83267
    commonly used groups of widgets: 
    89273
    90274        The format in which this field's initial value will be displayed.
    91275
    92     If no ``format`` argument is provided, the default format is ``'%H:%M:%S'``.
     276    If no ``format`` argument is provided, the default format is the first
     277    format found in :setting:`TIME_INPUT_FORMATS` and respects
     278    :ref:`format-localization`.
    93279
    94280.. class:: Textarea
    95281
    commonly used groups of widgets: 
    103289
    104290    .. attribute:: CheckboxInput.check_test
    105291
    106         A callable that takes the value of the CheckBoxInput
    107         and returns ``True`` if the checkbox should be checked for
    108         that value.
     292        A callable that takes the value of the CheckBoxInput and returns
     293        ``True`` if the checkbox should be checked for that value.
    109294
    110295.. class:: Select
    111296
    112297    Select widget: ``<select><option ...>...</select>``
    113298
    114     Requires that your field provides :attr:`~Field.choices`.
     299    .. attribute:: Select.choices
     300
     301        This attribute is optional when the field does not have a
     302        :attr:`~Field.choices` attribute. If it does, it will override anything
     303        you set here when the attribute is updated on the :class:`Field`.
    115304
    116305.. class:: NullBooleanSelect
    117306
    commonly used groups of widgets: 
    119308
    120309.. class:: SelectMultiple
    121310
    122     Select widget allowing multiple selection: ``<select
    123     multiple='multiple'>...</select>``
    124 
    125     Requires that your field provides :attr:`~Field.choices`.
     311    Similar to :class:`Select`, but allows multiple selection:
     312    ``<select multiple='multiple'>...</select>``
    126313
    127314.. class:: RadioSelect
    128315
    129     A list of radio buttons:
     316    Similar to :class:`Select`, but rendered as a list of radio buttons:
    130317
    131318    .. code-block:: html
    132319
    commonly used groups of widgets: 
    135322          ...
    136323        </ul>
    137324
    138     Requires that your field provides :attr:`~Field.choices`.
    139 
    140325.. class:: CheckboxSelectMultiple
    141326
    142     A list of checkboxes:
     327    Similar to :class:`SelectMultiple`, but rendered as a list of check
     328    buttons:
    143329
    144330    .. code-block:: html
    145331
    commonly used groups of widgets: 
    150336
    151337.. class:: MultiWidget
    152338
    153     Wrapper around multiple other widgets
     339    Wrapper around multiple other widgets. You'll probably want to use this
     340    class with :class:`MultiValueField`.
    154341
    155 .. class:: SplitDateTimeWidget
    156 
    157     Wrapper around two widgets: ``DateInput`` for the date, and ``TimeInput``
    158     for the time.
     342    Its ``render()`` method is different than other widgets', because it has to
     343    figure out how to split a single value for display in multiple widgets.
    159344
    160     Takes two optional arguments, ``date_format`` and ``time_format``, which
    161     work just like the ``format`` argument for ``DateInput`` and ``TimeInput``.
     345    Subclasses may implement ``format_output``, which takes the list of
     346    rendered widgets and returns a string of HTML that formats them any way
     347    you'd like.
    162348
    163 .. currentmodule:: django.forms.extras.widgets
     349    The ``value`` argument used when rendering can be one of two things:
    164350
    165 .. class:: SelectDateWidget
     351    * A ``list``.
     352    * A single value (e.g., a string) that is the "compressed" representation
     353      of a ``list`` of values.
    166354
    167     Wrapper around three select widgets: one each for month, day, and year.
    168     Note that this widget lives in a separate file from the standard widgets.
    169 
    170     Takes one optional argument:
    171 
    172     .. attribute:: List.years
    173 
    174         An optional list/tuple of years to use in the "year" select box.
    175         The default is a list containing the current year and the next 9 years.
     355    In the second case -- i.e., if the value is *not* a list -- ``render()``
     356    will first decompress the value into a ``list`` before rendering it. It
     357    does so by calling the ``decompress()`` method, which
     358    :class:`MultiWidget`'s subclasses must implement. This method takes a
     359    single "compressed" value and returns a ``list``. An example of this is how
     360    :class:`SplitDateTimeWidget` turns a :class:`datetime` value into a list
     361    with date and time split into two seperate values:
    176362
    177363    .. code-block:: python
    178364
    179         from django.forms.extras.widgets import SelectDateWidget
     365        class SplitDateTimeWidget(MultiWidget):
    180366
    181         date = forms.DateField(widget=SelectDateWidget())
     367            # ...
    182368
    183 Specifying widgets
    184 ------------------
    185 .. currentmodule:: django.forms
     369            def decompress(self, value):
     370                if value:
     371                    return [value.date(), value.time().replace(microsecond=0)]
     372                return [None, None]
    186373
    187 .. attribute:: Form.widget
     374    When ``render()`` executes its HTML rendering, each value in the list is
     375    rendered with the corresponding widget -- the first value is rendered in
     376    the first widget, the second value is rendered in the second widget, etc.
    188377
    189 Whenever you specify a field on a form, Django will use a default widget
    190 that is appropriate to the type of data that is to be displayed. To find
    191 which widget is used on which field, see the documentation for the
    192 built-in Field classes.
     378    :class:`MultiWidget` has one required argument:
    193379
    194 However, if you want to use a different widget for a field, you can -
    195 just use the 'widget' argument on the field definition. For example::
     380    .. attribute:: MultiWidget.widgets
    196381
    197     from django import forms
     382        An iterable containing the widgets needed.
    198383
    199     class CommentForm(forms.Form):
    200         name = forms.CharField()
    201         url = forms.URLField()
    202         comment = forms.CharField(widget=forms.Textarea)
     384.. class:: SplitDateTimeWidget
    203385
    204 This would specify a form with a comment that uses a larger Textarea widget,
    205 rather than the default TextInput widget.
     386    Wrapper (using :class:`MultiWidget`) around two widgets: :class:`DateInput`
     387    for the date, and :class:`TimeInput` for the time.
    206388
    207 Customizing widget instances
    208 ----------------------------
     389    ``SplitDateTimeWidget`` has two optional attributes:
    209390
    210 When Django renders a widget as HTML, it only renders the bare minimum
    211 HTML - Django doesn't add a class definition, or any other widget-specific
    212 attributes. This means that all 'TextInput' widgets will appear the same
    213 on your Web page.
     391    .. attribute:: SplitDateTimeWidget.date_format
    214392
    215 If you want to make one widget look different to another, you need to
    216 specify additional attributes for each widget. When you specify a
    217 widget, you can provide a list of attributes that will be added to the
    218 rendered HTML for the widget.
     393        Similar to :attr:`DateInput.format`
    219394
    220 For example, take the following simple form::
     395    .. attribute:: SplitDateTimeWidget.time_format
    221396
    222     class CommentForm(forms.Form):
    223         name = forms.CharField()
    224         url = forms.URLField()
    225         comment = forms.CharField()
     397        Similar to :attr:`TimeInput.format`
    226398
    227 This form will include three default TextInput widgets, with default rendering -
    228 no CSS class, no extra attributes. This means that the input boxes provided for
    229 each widget will be rendered exactly the same::
    230399
    231     >>> f = CommentForm(auto_id=False)
    232     >>> f.as_table()
    233     <tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
    234     <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
    235     <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
     400.. class:: SplitHiddenDateTimeWidget
    236401
     402    Similar to :class:`SplitDateTimeWidget`, but uses :class:`HiddenInput` for
     403    both date and time.
    237404
    238 On a real Web page, you probably don't want every widget to look the same. You
    239 might want a larger input element for the comment, and you might want the 'name'
    240 widget to have some special CSS class. To do this, you use the ``attrs``
    241 argument when creating the widget:
     405.. currentmodule:: django.forms.widgets.extras
    242406
    243 .. attribute:: Widget.attrs
     407.. class:: SelectDateWidget
    244408
    245 For example::
     409    Wrapper around three :class:`~django.forms.Select` widgets: one each for
     410    month, day, and year. Note that this widget lives in a separate file from
     411    the standard widgets.
    246412
    247     class CommentForm(forms.Form):
    248         name = forms.CharField(
    249                     widget=forms.TextInput(attrs={'class':'special'}))
    250         url = forms.URLField()
    251         comment = forms.CharField(
    252                    widget=forms.TextInput(attrs={'size':'40'}))
     413    Takes one optional argument:
    253414
    254 Django will then include the extra attributes in the rendered output::
     415    .. attribute:: SelectDateWidget.years
    255416
    256     >>> f = CommentForm(auto_id=False)
    257     >>> f.as_table()
    258     <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
    259     <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
    260     <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
     417        An optional list/tuple of years to use in the "year" select box.
     418        The default is a list containing the current year and the next 9 years.
Back to Top