mirror of
				https://github.com/django/django.git
				synced 2025-10-26 07:06:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1000 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			1000 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| =======
 | |
| Widgets
 | |
| =======
 | |
| 
 | |
| .. module:: django.forms.widgets
 | |
|    :synopsis: Django's built-in form widgets.
 | |
| 
 | |
| .. currentmodule:: django.forms
 | |
| 
 | |
| A widget is Django's representation of an HTML input element. The widget
 | |
| handles the rendering of the HTML, and the extraction of data from a GET/POST
 | |
| dictionary that corresponds to the widget.
 | |
| 
 | |
| The HTML generated by the built-in widgets uses HTML5 syntax, targeting
 | |
| ``<!DOCTYPE html>``. For example, it uses boolean attributes such as ``checked``
 | |
| rather than the XHTML style of ``checked='checked'``.
 | |
| 
 | |
| .. tip::
 | |
| 
 | |
|     Widgets should not be confused with the :doc:`form fields </ref/forms/fields>`.
 | |
|     Form fields deal with the logic of input validation and are used directly
 | |
|     in templates. Widgets deal with rendering of HTML form input elements on
 | |
|     the web page and extraction of raw submitted data. However, widgets do
 | |
|     need to be :ref:`assigned <widget-to-field>` to form fields.
 | |
| 
 | |
| .. _widget-to-field:
 | |
| 
 | |
| Specifying widgets
 | |
| ==================
 | |
| 
 | |
| Whenever you specify a field on a form, Django will use a default widget
 | |
| that is appropriate to the type of data that is to be displayed. To find
 | |
| which widget is used on which field, see the documentation about
 | |
| :ref:`built-in-fields`.
 | |
| 
 | |
| However, if you want to use a different widget for a field, you can
 | |
| use the :attr:`~Field.widget` argument on the field definition. For example::
 | |
| 
 | |
|     from django import forms
 | |
| 
 | |
| 
 | |
|     class CommentForm(forms.Form):
 | |
|         name = forms.CharField()
 | |
|         url = forms.URLField()
 | |
|         comment = forms.CharField(widget=forms.Textarea)
 | |
| 
 | |
| This would specify a form with a comment that uses a larger :class:`Textarea`
 | |
| widget, rather than the default :class:`TextInput` widget.
 | |
| 
 | |
| Setting arguments for widgets
 | |
| =============================
 | |
| 
 | |
| Many widgets have optional extra arguments; they can be set when defining the
 | |
| widget on the field. In the following example, the
 | |
| :attr:`~django.forms.SelectDateWidget.years` attribute is set for a
 | |
| :class:`~django.forms.SelectDateWidget`::
 | |
| 
 | |
|     from django import forms
 | |
| 
 | |
|     BIRTH_YEAR_CHOICES = ["1980", "1981", "1982"]
 | |
|     FAVORITE_COLORS_CHOICES = {
 | |
|         "blue": "Blue",
 | |
|         "green": "Green",
 | |
|         "black": "Black",
 | |
|     }
 | |
| 
 | |
| 
 | |
|     class SimpleForm(forms.Form):
 | |
|         birth_year = forms.DateField(
 | |
|             widget=forms.SelectDateWidget(years=BIRTH_YEAR_CHOICES)
 | |
|         )
 | |
|         favorite_colors = forms.MultipleChoiceField(
 | |
|             required=False,
 | |
|             widget=forms.CheckboxSelectMultiple,
 | |
|             choices=FAVORITE_COLORS_CHOICES,
 | |
|         )
 | |
| 
 | |
| See the :ref:`built-in widgets` for more information about which widgets
 | |
| are available and which arguments they accept.
 | |
| 
 | |
| Widgets inheriting from the ``Select`` widget
 | |
| =============================================
 | |
| 
 | |
| Widgets inheriting from the :class:`Select` widget deal with choices. They
 | |
| present the user with a list of options to choose from. The different widgets
 | |
| present this choice differently; the :class:`Select` widget itself uses a
 | |
| ``<select>`` HTML list representation, while :class:`RadioSelect` uses radio
 | |
| buttons.
 | |
| 
 | |
| :class:`Select` widgets are used by default on :class:`ChoiceField` fields. The
 | |
| choices displayed on the widget are inherited from the :class:`ChoiceField` and
 | |
| changing :attr:`ChoiceField.choices` will update :attr:`Select.choices`. For
 | |
| example:
 | |
| 
 | |
| .. code-block:: pycon
 | |
| 
 | |
|     >>> from django import forms
 | |
|     >>> CHOICES = {"1": "First", "2": "Second"}
 | |
|     >>> choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
 | |
|     >>> choice_field.choices
 | |
|     [('1', 'First'), ('2', 'Second')]
 | |
|     >>> choice_field.widget.choices
 | |
|     [('1', 'First'), ('2', 'Second')]
 | |
|     >>> choice_field.widget.choices = []
 | |
|     >>> choice_field.choices = [("1", "First and only")]
 | |
|     >>> choice_field.widget.choices
 | |
|     [('1', 'First and only')]
 | |
| 
 | |
| Widgets which offer a :attr:`~Select.choices` attribute can however be used
 | |
| with fields which are not based on choice -- such as a :class:`CharField` --
 | |
| but it is recommended to use a :class:`ChoiceField`-based field when the
 | |
| choices are inherent to the model and not just the representational widget.
 | |
| 
 | |
| Customizing widget instances
 | |
| ============================
 | |
| 
 | |
| When Django renders a widget as HTML, it only renders very minimal markup -
 | |
| Django doesn't add class names, or any other widget-specific attributes. This
 | |
| means, for example, that all :class:`TextInput` widgets will appear the same
 | |
| on your web pages.
 | |
| 
 | |
| There are two ways to customize widgets: :ref:`per widget instance
 | |
| <styling-widget-instances>` and :ref:`per widget class <styling-widget-classes>`.
 | |
| 
 | |
| .. _styling-widget-instances:
 | |
| 
 | |
| Styling widget instances
 | |
| ------------------------
 | |
| 
 | |
| If you want to make one widget instance look different from another, you will
 | |
| need to specify additional attributes at the time when the widget object is
 | |
| instantiated and assigned to a form field (and perhaps add some rules to your
 | |
| CSS files).
 | |
| 
 | |
| For example, take the following form::
 | |
| 
 | |
|     from django import forms
 | |
| 
 | |
| 
 | |
|     class CommentForm(forms.Form):
 | |
|         name = forms.CharField()
 | |
|         url = forms.URLField()
 | |
|         comment = forms.CharField()
 | |
| 
 | |
| This form will include three default :class:`TextInput` widgets, with default
 | |
| rendering -- no CSS class, no extra attributes. This means that the input boxes
 | |
| provided for each widget will be rendered exactly the same:
 | |
| 
 | |
| .. code-block:: pycon
 | |
| 
 | |
|     >>> f = CommentForm(auto_id=False)
 | |
|     >>> print(f)
 | |
|     <div>Name:<input type="text" name="name" required></div>
 | |
|     <div>Url:<input type="url" name="url" required></div>
 | |
|     <div>Comment:<input type="text" name="comment" required></div>
 | |
| 
 | |
| On a real web page, you probably don't want every widget to look the same. You
 | |
| might want a larger input element for the comment, and you might want the
 | |
| 'name' widget to have some special CSS class. It is also possible to specify
 | |
| the 'type' attribute to take advantage of the new HTML5 input types.  To do
 | |
| this, you use the :attr:`Widget.attrs` argument when creating the widget::
 | |
| 
 | |
|     class CommentForm(forms.Form):
 | |
|         name = forms.CharField(widget=forms.TextInput(attrs={"class": "special"}))
 | |
|         url = forms.URLField()
 | |
|         comment = forms.CharField(widget=forms.TextInput(attrs={"size": "40"}))
 | |
| 
 | |
| You can also modify a widget in the form definition::
 | |
| 
 | |
|     class CommentForm(forms.Form):
 | |
|         name = forms.CharField()
 | |
|         url = forms.URLField()
 | |
|         comment = forms.CharField()
 | |
| 
 | |
|         name.widget.attrs.update({"class": "special"})
 | |
|         comment.widget.attrs.update(size="40")
 | |
| 
 | |
| Or if the field isn't declared directly on the form (such as model form fields),
 | |
| you can use the :attr:`Form.fields` attribute::
 | |
| 
 | |
|     class CommentForm(forms.ModelForm):
 | |
|         def __init__(self, *args, **kwargs):
 | |
|             super().__init__(*args, **kwargs)
 | |
|             self.fields["name"].widget.attrs.update({"class": "special"})
 | |
|             self.fields["comment"].widget.attrs.update(size="40")
 | |
| 
 | |
| Django will then include the extra attributes in the rendered output:
 | |
| 
 | |
|     >>> f = CommentForm(auto_id=False)
 | |
|     >>> print(f)
 | |
|     <div>Name:<input type="text" name="name" class="special" required></div>
 | |
|     <div>Url:<input type="url" name="url" required></div>
 | |
|     <div>Comment:<input type="text" name="comment" size="40" required></div>
 | |
| 
 | |
| You can also set the HTML ``id`` using :attr:`~Widget.attrs`. See
 | |
| :attr:`BoundField.id_for_label` for an example.
 | |
| 
 | |
| .. _styling-widget-classes:
 | |
| 
 | |
| Styling widget classes
 | |
| ----------------------
 | |
| 
 | |
| With widgets, it is possible to add assets (``css`` and ``javascript``)
 | |
| and more deeply customize their appearance and behavior.
 | |
| 
 | |
| In a nutshell, you will need to subclass the widget and either
 | |
| :ref:`define a "Media" inner class  <assets-as-a-static-definition>` or
 | |
| :ref:`create a "media" property <dynamic-property>`.
 | |
| 
 | |
| These methods involve somewhat advanced Python programming and are described in
 | |
| detail in the :doc:`Form Assets </topics/forms/media>` topic guide.
 | |
| 
 | |
| .. _base-widget-classes:
 | |
| 
 | |
| Base widget classes
 | |
| ===================
 | |
| 
 | |
| Base widget classes :class:`Widget` and :class:`MultiWidget` are subclassed by
 | |
| all the :ref:`built-in widgets <built-in widgets>` and may serve as a
 | |
| foundation for custom widgets.
 | |
| 
 | |
| ``Widget``
 | |
| ----------
 | |
| 
 | |
| .. class:: Widget(attrs=None)
 | |
| 
 | |
|     This abstract class cannot be rendered, but provides the basic attribute
 | |
|     :attr:`~Widget.attrs`.  You may also implement or override the
 | |
|     :meth:`~Widget.render()` method on custom widgets.
 | |
| 
 | |
|     .. attribute:: Widget.attrs
 | |
| 
 | |
|         A dictionary containing HTML attributes to be set on the rendered
 | |
|         widget.
 | |
| 
 | |
|         .. code-block:: pycon
 | |
| 
 | |
|             >>> from django import forms
 | |
|             >>> name = forms.TextInput(attrs={"size": 10, "title": "Your name"})
 | |
|             >>> name.render("name", "A name")
 | |
|             '<input title="Your name" type="text" name="name" value="A name" size="10">'
 | |
| 
 | |
|         If you assign a value of ``True`` or ``False`` to an attribute,
 | |
|         it will be rendered as an HTML5 boolean attribute:
 | |
| 
 | |
|         .. code-block:: pycon
 | |
| 
 | |
|             >>> name = forms.TextInput(attrs={"required": True})
 | |
|             >>> name.render("name", "A name")
 | |
|             '<input name="name" type="text" value="A name" required>'
 | |
|             >>>
 | |
|             >>> name = forms.TextInput(attrs={"required": False})
 | |
|             >>> name.render("name", "A name")
 | |
|             '<input name="name" type="text" value="A name">'
 | |
| 
 | |
|     .. attribute:: Widget.supports_microseconds
 | |
| 
 | |
|        An attribute that defaults to ``True``. If set to ``False``, the
 | |
|        microseconds part of :class:`~datetime.datetime` and
 | |
|        :class:`~datetime.time` values will be set to ``0``.
 | |
| 
 | |
|     .. method:: format_value(value)
 | |
| 
 | |
|         Cleans and returns a value for use in the widget template. ``value``
 | |
|         isn't guaranteed to be valid input, therefore subclass implementations
 | |
|         should program defensively.
 | |
| 
 | |
|     .. method:: get_context(name, value, attrs)
 | |
| 
 | |
|         Returns a dictionary of values to use when rendering the widget
 | |
|         template. By default, the dictionary contains a single key,
 | |
|         ``'widget'``, which is a dictionary representation of the widget
 | |
|         containing the following keys:
 | |
| 
 | |
|         * ``'name'``: The name of the field from the ``name`` argument.
 | |
|         * ``'is_hidden'``: A boolean indicating whether or not this widget is
 | |
|           hidden.
 | |
|         * ``'required'``: A boolean indicating whether or not the field for
 | |
|           this widget is required.
 | |
|         * ``'value'``: The value as returned by :meth:`format_value`.
 | |
|         * ``'attrs'``: HTML attributes to be set on the rendered widget. The
 | |
|           combination of the :attr:`attrs` attribute and the ``attrs`` argument.
 | |
|         * ``'template_name'``: The value of ``self.template_name``.
 | |
| 
 | |
|         ``Widget`` subclasses can provide custom context values by overriding
 | |
|         this method.
 | |
| 
 | |
|     .. method:: id_for_label(id_)
 | |
| 
 | |
|         Returns the HTML ID attribute of this widget for use by a ``<label>``,
 | |
|         given the ID of the field. Returns an empty string 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, renderer=None)
 | |
| 
 | |
|         Renders a widget to HTML using the given renderer. If ``renderer`` is
 | |
|         ``None``, the renderer from the :setting:`FORM_RENDERER` setting is
 | |
|         used.
 | |
| 
 | |
|     .. method:: value_from_datadict(data, files, name)
 | |
| 
 | |
|         Given a dictionary of data and this widget's name, returns the value
 | |
|         of this widget. ``files`` may contain data coming from
 | |
|         :attr:`request.FILES <django.http.HttpRequest.FILES>`. Returns ``None``
 | |
|         if a value wasn't provided. Note also that ``value_from_datadict`` may
 | |
|         be called more than once during handling of form data, so if you
 | |
|         customize it and add expensive processing, you should implement some
 | |
|         caching mechanism yourself.
 | |
| 
 | |
|     .. method:: value_omitted_from_data(data, files, name)
 | |
| 
 | |
|         Given ``data`` and ``files`` dictionaries and this widget's name,
 | |
|         returns whether or not there's data or files for the widget.
 | |
| 
 | |
|         The method's result affects whether or not a field in a model form
 | |
|         :ref:`falls back to its default <topics-modelform-save>`.
 | |
| 
 | |
|         Special cases are :class:`~django.forms.CheckboxInput`,
 | |
|         :class:`~django.forms.CheckboxSelectMultiple`, and
 | |
|         :class:`~django.forms.SelectMultiple`, which always return
 | |
|         ``False`` because an unchecked checkbox and unselected
 | |
|         ``<select multiple>`` don't appear in the data of an HTML form
 | |
|         submission, so it's unknown whether or not the user submitted a value.
 | |
| 
 | |
|     .. attribute:: Widget.use_fieldset
 | |
| 
 | |
|         An attribute to identify if the widget should be grouped in a
 | |
|         ``<fieldset>`` with a ``<legend>`` when rendered. Defaults to ``False``
 | |
|         but is ``True`` when the widget contains multiple ``<input>`` tags such as
 | |
|         :class:`~django.forms.CheckboxSelectMultiple`,
 | |
|         :class:`~django.forms.RadioSelect`,
 | |
|         :class:`~django.forms.MultiWidget`,
 | |
|         :class:`~django.forms.SplitDateTimeWidget`, and
 | |
|         :class:`~django.forms.SelectDateWidget`.
 | |
| 
 | |
|     .. method:: use_required_attribute(initial)
 | |
| 
 | |
|         Given a form field's ``initial`` value, returns whether or not the
 | |
|         widget can be rendered with the ``required`` HTML attribute. Forms use
 | |
|         this method along with :attr:`Field.required
 | |
|         <django.forms.Field.required>` and :attr:`Form.use_required_attribute
 | |
|         <django.forms.Form.use_required_attribute>` to determine whether or not
 | |
|         to display the ``required`` attribute for each field.
 | |
| 
 | |
|         By default, returns ``False`` for hidden widgets and ``True``
 | |
|         otherwise. Special cases are :class:`~django.forms.FileInput` and
 | |
|         :class:`~django.forms.ClearableFileInput`, which return ``False`` when
 | |
|         ``initial`` is set, and :class:`~django.forms.CheckboxSelectMultiple`,
 | |
|         which always returns ``False`` because browser validation would require
 | |
|         all checkboxes to be checked instead of at least one.
 | |
| 
 | |
|         Override this method in custom widgets that aren't compatible with
 | |
|         browser validation. For example, a WSYSIWG text editor widget backed by
 | |
|         a hidden ``textarea`` element may want to always return ``False`` to
 | |
|         avoid browser validation on the hidden field.
 | |
| 
 | |
| ``MultiWidget``
 | |
| ---------------
 | |
| 
 | |
| .. class:: MultiWidget(widgets, attrs=None)
 | |
| 
 | |
|     A widget that is composed of multiple widgets.
 | |
|     :class:`~django.forms.MultiWidget` works hand in hand with the
 | |
|     :class:`~django.forms.MultiValueField`.
 | |
| 
 | |
|     :class:`MultiWidget` has one required argument:
 | |
| 
 | |
|     .. attribute:: MultiWidget.widgets
 | |
| 
 | |
|         An iterable containing the widgets needed. For example:
 | |
| 
 | |
|         .. code-block:: pycon
 | |
| 
 | |
|             >>> from django.forms import MultiWidget, TextInput
 | |
|             >>> widget = MultiWidget(widgets=[TextInput, TextInput])
 | |
|             >>> widget.render("name", ["john", "paul"])
 | |
|             '<input type="text" name="name_0" value="john"><input type="text" name="name_1" value="paul">'
 | |
| 
 | |
|         You may provide a dictionary in order to specify custom suffixes for
 | |
|         the ``name`` attribute on each subwidget. In this case, for each
 | |
|         ``(key, widget)`` pair, the key will be appended to the ``name`` of the
 | |
|         widget in order to generate the attribute value. You may provide the
 | |
|         empty string (``''``) for a single key, in order to suppress the suffix
 | |
|         for one widget. For example:
 | |
| 
 | |
|         .. code-block:: pycon
 | |
| 
 | |
|             >>> widget = MultiWidget(widgets={"": TextInput, "last": TextInput})
 | |
|             >>> widget.render("name", ["john", "paul"])
 | |
|             '<input type="text" name="name" value="john"><input type="text" name="name_last" value="paul">'
 | |
| 
 | |
|     And one required method:
 | |
| 
 | |
|     .. method:: decompress(value)
 | |
| 
 | |
|         This method takes a single "compressed" value from the field and
 | |
|         returns a list of "decompressed" values. The input value can be
 | |
|         assumed valid, but not necessarily non-empty.
 | |
| 
 | |
|         This method **must be implemented** by the subclass, and since the
 | |
|         value may be empty, the implementation must be defensive.
 | |
| 
 | |
|         The rationale behind "decompression" is that it is necessary to "split"
 | |
|         the combined value of the form field into the values for each widget.
 | |
| 
 | |
|         An example of this is how :class:`SplitDateTimeWidget` turns a
 | |
|         :class:`~datetime.datetime` value into a list with date and time split
 | |
|         into two separate values::
 | |
| 
 | |
|             from django.forms import MultiWidget
 | |
| 
 | |
| 
 | |
|             class SplitDateTimeWidget(MultiWidget):
 | |
|                 # ...
 | |
| 
 | |
|                 def decompress(self, value):
 | |
|                     if value:
 | |
|                         return [value.date(), value.time()]
 | |
|                     return [None, None]
 | |
| 
 | |
|         .. tip::
 | |
| 
 | |
|             Note that :class:`~django.forms.MultiValueField` has a
 | |
|             complementary method :meth:`~django.forms.MultiValueField.compress`
 | |
|             with the opposite responsibility - to combine cleaned values of
 | |
|             all member fields into one.
 | |
| 
 | |
|     It provides some custom context:
 | |
| 
 | |
|     .. method:: get_context(name, value, attrs)
 | |
| 
 | |
|         In addition to the ``'widget'`` key described in
 | |
|         :meth:`Widget.get_context`, ``MultiWidget`` adds a
 | |
|         ``widget['subwidgets']`` key.
 | |
| 
 | |
|         These can be looped over in the widget template:
 | |
| 
 | |
|         .. code-block:: html+django
 | |
| 
 | |
|             {% for subwidget in widget.subwidgets %}
 | |
|                 {% include subwidget.template_name with widget=subwidget %}
 | |
|             {% endfor %}
 | |
| 
 | |
|     Here's an example widget which subclasses :class:`MultiWidget` to display
 | |
|     a date with the day, month, and year in different select boxes. This widget
 | |
|     is intended to be used with a :class:`~django.forms.DateField` rather than
 | |
|     a :class:`~django.forms.MultiValueField`, thus we have implemented
 | |
|     :meth:`~Widget.value_from_datadict`::
 | |
| 
 | |
|         from datetime import date
 | |
|         from django import forms
 | |
| 
 | |
| 
 | |
|         class DateSelectorWidget(forms.MultiWidget):
 | |
|             def __init__(self, attrs=None):
 | |
|                 days = {day: day for day in range(1, 32)}
 | |
|                 months = {month: month for month in range(1, 13)}
 | |
|                 years = {year: year for year in [2018, 2019, 2020]}
 | |
|                 widgets = [
 | |
|                     forms.Select(attrs=attrs, choices=days),
 | |
|                     forms.Select(attrs=attrs, choices=months),
 | |
|                     forms.Select(attrs=attrs, choices=years),
 | |
|                 ]
 | |
|                 super().__init__(widgets, attrs)
 | |
| 
 | |
|             def decompress(self, value):
 | |
|                 if isinstance(value, date):
 | |
|                     return [value.day, value.month, value.year]
 | |
|                 elif isinstance(value, str):
 | |
|                     year, month, day = value.split("-")
 | |
|                     return [day, month, year]
 | |
|                 return [None, None, None]
 | |
| 
 | |
|             def value_from_datadict(self, data, files, name):
 | |
|                 day, month, year = super().value_from_datadict(data, files, name)
 | |
|                 # DateField expects a single string that it can parse into a date.
 | |
|                 return "{}-{}-{}".format(year, month, day)
 | |
| 
 | |
|     The constructor creates several :class:`Select` widgets in a list. The
 | |
|     ``super()`` method uses this list to set up the widget.
 | |
| 
 | |
|     The required method :meth:`~MultiWidget.decompress` breaks up a
 | |
|     ``datetime.date`` value into the day, month, and year values corresponding
 | |
|     to each widget. If an invalid date was selected, such as the non-existent
 | |
|     30th February, the :class:`~django.forms.DateField` passes this method a
 | |
|     string instead, so that needs parsing. The final ``return`` handles when
 | |
|     ``value`` is ``None``, meaning we don't have any defaults for our
 | |
|     subwidgets.
 | |
| 
 | |
|     The default implementation of :meth:`~Widget.value_from_datadict` returns a
 | |
|     list of values corresponding to each ``Widget``. This is appropriate when
 | |
|     using a ``MultiWidget`` with a :class:`~django.forms.MultiValueField`. But
 | |
|     since we want to use this widget with a :class:`~django.forms.DateField`,
 | |
|     which takes a single value, we have overridden this method. The
 | |
|     implementation here combines the data from the subwidgets into a string in
 | |
|     the format that :class:`~django.forms.DateField` expects.
 | |
| 
 | |
| .. _built-in widgets:
 | |
| 
 | |
| Built-in widgets
 | |
| ================
 | |
| 
 | |
| Django provides a representation of all the basic HTML widgets, plus some
 | |
| commonly used groups of widgets in the ``django.forms.widgets`` module,
 | |
| including :ref:`the input of text <text-widgets>`, :ref:`various checkboxes
 | |
| and selectors <selector-widgets>`, :ref:`uploading files <file-upload-widgets>`,
 | |
| and :ref:`handling of multi-valued input <composite-widgets>`.
 | |
| 
 | |
| .. _text-widgets:
 | |
| 
 | |
| Widgets handling input of text
 | |
| ------------------------------
 | |
| 
 | |
| These widgets make use of the HTML elements ``input`` and ``textarea``.
 | |
| 
 | |
| ``TextInput``
 | |
| ~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: TextInput
 | |
| 
 | |
|     * ``input_type``: ``'text'``
 | |
|     * ``template_name``: ``'django/forms/widgets/text.html'``
 | |
|     * Renders as: ``<input type="text" ...>``
 | |
| 
 | |
| ``NumberInput``
 | |
| ~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: NumberInput
 | |
| 
 | |
|     * ``input_type``: ``'number'``
 | |
|     * ``template_name``: ``'django/forms/widgets/number.html'``
 | |
|     * Renders as: ``<input type="number" ...>``
 | |
| 
 | |
|     Beware that not all browsers support entering localized numbers in
 | |
|     ``number`` input types. Django itself avoids using them for fields having
 | |
|     their :attr:`~django.forms.Field.localize` property set to ``True``.
 | |
| 
 | |
| ``EmailInput``
 | |
| ~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: EmailInput
 | |
| 
 | |
|     * ``input_type``: ``'email'``
 | |
|     * ``template_name``: ``'django/forms/widgets/email.html'``
 | |
|     * Renders as: ``<input type="email" ...>``
 | |
| 
 | |
| ``URLInput``
 | |
| ~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: URLInput
 | |
| 
 | |
|     * ``input_type``: ``'url'``
 | |
|     * ``template_name``: ``'django/forms/widgets/url.html'``
 | |
|     * Renders as: ``<input type="url" ...>``
 | |
| 
 | |
| ``PasswordInput``
 | |
| ~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: PasswordInput
 | |
| 
 | |
|     * ``input_type``: ``'password'``
 | |
|     * ``template_name``: ``'django/forms/widgets/password.html'``
 | |
|     * Renders as: ``<input type="password" ...>``
 | |
| 
 | |
|     Takes one optional argument:
 | |
| 
 | |
|     .. attribute:: PasswordInput.render_value
 | |
| 
 | |
|         Determines whether the widget will have a value filled in when the
 | |
|         form is re-displayed after a validation error (default is ``False``).
 | |
| 
 | |
| ``HiddenInput``
 | |
| ~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: HiddenInput
 | |
| 
 | |
|     * ``input_type``: ``'hidden'``
 | |
|     * ``template_name``: ``'django/forms/widgets/hidden.html'``
 | |
|     * Renders as: ``<input type="hidden" ...>``
 | |
| 
 | |
|     Note that there also is a :class:`MultipleHiddenInput` widget that
 | |
|     encapsulates a set of hidden input elements.
 | |
| 
 | |
| ``DateInput``
 | |
| ~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: DateInput
 | |
| 
 | |
|     * ``input_type``: ``'text'``
 | |
|     * ``template_name``: ``'django/forms/widgets/date.html'``
 | |
|     * Renders as: ``<input type="text" ...>``
 | |
| 
 | |
|     Takes same arguments as :class:`TextInput`, with one more optional argument:
 | |
| 
 | |
|     .. attribute:: DateInput.format
 | |
| 
 | |
|         The format in which this field's initial value will be displayed.
 | |
| 
 | |
|     If no ``format`` argument is provided, the default format is the first
 | |
|     format found in :setting:`DATE_INPUT_FORMATS` and respects
 | |
|     :doc:`/topics/i18n/formatting`. ``%U``, ``%W``, and ``%j`` formats are not
 | |
|     supported by this widget.
 | |
| 
 | |
| ``DateTimeInput``
 | |
| ~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: DateTimeInput
 | |
| 
 | |
|     * ``input_type``: ``'text'``
 | |
|     * ``template_name``: ``'django/forms/widgets/datetime.html'``
 | |
|     * Renders as: ``<input type="text" ...>``
 | |
| 
 | |
|     Takes same arguments as :class:`TextInput`, with one more optional argument:
 | |
| 
 | |
|     .. attribute:: DateTimeInput.format
 | |
| 
 | |
|         The format in which this field's initial value will be displayed.
 | |
| 
 | |
|     If no ``format`` argument is provided, the default format is the first
 | |
|     format found in :setting:`DATETIME_INPUT_FORMATS` and respects
 | |
|     :doc:`/topics/i18n/formatting`. ``%U``, ``%W``, and ``%j`` formats are not
 | |
|     supported by this widget.
 | |
| 
 | |
|     By default, the microseconds part of the time value is always set to ``0``.
 | |
|     If microseconds are required, use a subclass with the
 | |
|     :attr:`~Widget.supports_microseconds` attribute set to ``True``.
 | |
| 
 | |
| ``TimeInput``
 | |
| ~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: TimeInput
 | |
| 
 | |
|     * ``input_type``: ``'text'``
 | |
|     * ``template_name``: ``'django/forms/widgets/time.html'``
 | |
|     * Renders as: ``<input type="text" ...>``
 | |
| 
 | |
|     Takes same arguments as :class:`TextInput`, with one more optional argument:
 | |
| 
 | |
|     .. attribute:: TimeInput.format
 | |
| 
 | |
|         The format in which this field's initial value will be displayed.
 | |
| 
 | |
|     If no ``format`` argument is provided, the default format is the first
 | |
|     format found in :setting:`TIME_INPUT_FORMATS` and respects
 | |
|     :doc:`/topics/i18n/formatting`.
 | |
| 
 | |
|     For the treatment of microseconds, see :class:`DateTimeInput`.
 | |
| 
 | |
| ``Textarea``
 | |
| ~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: Textarea
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/textarea.html'``
 | |
|     * Renders as: ``<textarea>...</textarea>``
 | |
| 
 | |
| .. _selector-widgets:
 | |
| 
 | |
| Selector and checkbox widgets
 | |
| -----------------------------
 | |
| 
 | |
| These widgets make use of the HTML elements ``<select>``,
 | |
| ``<input type="checkbox">``, and ``<input type="radio">``.
 | |
| 
 | |
| Widgets that render multiple choices have an ``option_template_name`` attribute
 | |
| that specifies the template used to render each choice. For example, for the
 | |
| :class:`Select` widget, ``select_option.html`` renders the ``<option>`` for a
 | |
| ``<select>``.
 | |
| 
 | |
| ``CheckboxInput``
 | |
| ~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: CheckboxInput
 | |
| 
 | |
|     * ``input_type``: ``'checkbox'``
 | |
|     * ``template_name``: ``'django/forms/widgets/checkbox.html'``
 | |
|     * Renders as: ``<input type="checkbox" ...>``
 | |
| 
 | |
|     Takes one optional argument:
 | |
| 
 | |
|     .. attribute:: CheckboxInput.check_test
 | |
| 
 | |
|         A callable that takes the value of the ``CheckboxInput`` and returns
 | |
|         ``True`` if the checkbox should be checked for that value.
 | |
| 
 | |
| ``Select``
 | |
| ~~~~~~~~~~
 | |
| 
 | |
| .. class:: Select
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/select.html'``
 | |
|     * ``option_template_name``: ``'django/forms/widgets/select_option.html'``
 | |
|     * Renders as: ``<select><option ...>...</select>``
 | |
| 
 | |
|     .. attribute:: Select.choices
 | |
| 
 | |
|         This attribute is optional when the form field does not have a
 | |
|         ``choices`` attribute. If it does, it will override anything you set
 | |
|         here when the attribute is updated on the :class:`Field`.
 | |
| 
 | |
| ``NullBooleanSelect``
 | |
| ~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: NullBooleanSelect
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/select.html'``
 | |
|     * ``option_template_name``: ``'django/forms/widgets/select_option.html'``
 | |
| 
 | |
|     Select widget with options 'Unknown', 'Yes' and 'No'
 | |
| 
 | |
| ``SelectMultiple``
 | |
| ~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: SelectMultiple
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/select.html'``
 | |
|     * ``option_template_name``: ``'django/forms/widgets/select_option.html'``
 | |
| 
 | |
|     Similar to :class:`Select`, but allows multiple selection:
 | |
|     ``<select multiple>...</select>``
 | |
| 
 | |
| ``RadioSelect``
 | |
| ~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: RadioSelect
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/radio.html'``
 | |
|     * ``option_template_name``: ``'django/forms/widgets/radio_option.html'``
 | |
| 
 | |
|     Similar to :class:`Select`, but rendered as a list of radio buttons within
 | |
|     ``<div>`` tags:
 | |
| 
 | |
|     .. code-block:: html
 | |
| 
 | |
|         <div>
 | |
|           <div><input type="radio" name="..."></div>
 | |
|           ...
 | |
|         </div>
 | |
| 
 | |
|     For more granular control over the generated markup, you can loop over the
 | |
|     radio buttons in the template. Assuming a form ``myform`` with a field
 | |
|     ``beatles`` that uses a ``RadioSelect`` as its widget:
 | |
| 
 | |
|     .. code-block:: html+django
 | |
| 
 | |
|         <fieldset>
 | |
|             <legend>{{ myform.beatles.label }}</legend>
 | |
|             {% for radio in myform.beatles %}
 | |
|             <div class="myradio">
 | |
|                 {{ radio }}
 | |
|             </div>
 | |
|             {% endfor %}
 | |
|         </fieldset>
 | |
| 
 | |
|     This would generate the following HTML:
 | |
| 
 | |
|     .. code-block:: html
 | |
| 
 | |
|         <fieldset>
 | |
|             <legend>Radio buttons</legend>
 | |
|             <div class="myradio">
 | |
|                 <label for="id_beatles_0"><input id="id_beatles_0" name="beatles" type="radio" value="john" required> John</label>
 | |
|             </div>
 | |
|             <div class="myradio">
 | |
|                 <label for="id_beatles_1"><input id="id_beatles_1" name="beatles" type="radio" value="paul" required> Paul</label>
 | |
|             </div>
 | |
|             <div class="myradio">
 | |
|                 <label for="id_beatles_2"><input id="id_beatles_2" name="beatles" type="radio" value="george" required> George</label>
 | |
|             </div>
 | |
|             <div class="myradio">
 | |
|                 <label for="id_beatles_3"><input id="id_beatles_3" name="beatles" type="radio" value="ringo" required> Ringo</label>
 | |
|             </div>
 | |
|         </fieldset>
 | |
| 
 | |
|     That included the ``<label>`` tags. To get more granular, you can use each
 | |
|     radio button's ``tag``, ``choice_label`` and ``id_for_label`` attributes.
 | |
|     For example, this template...
 | |
| 
 | |
|     .. code-block:: html+django
 | |
| 
 | |
|         <fieldset>
 | |
|             <legend>{{ myform.beatles.label }}</legend>
 | |
|             {% for radio in myform.beatles %}
 | |
|             <label for="{{ radio.id_for_label }}">
 | |
|                 {{ radio.choice_label }}
 | |
|                 <span class="radio">{{ radio.tag }}</span>
 | |
|             </label>
 | |
|             {% endfor %}
 | |
|         </fieldset>
 | |
| 
 | |
|     ...will result in the following HTML:
 | |
| 
 | |
|     .. code-block:: html
 | |
| 
 | |
|         <fieldset>
 | |
|             <legend>Radio buttons</legend>
 | |
|             <label for="id_beatles_0">
 | |
|                 John
 | |
|                 <span class="radio"><input id="id_beatles_0" name="beatles" type="radio" value="john" required></span>
 | |
|             </label>
 | |
|             <label for="id_beatles_1">
 | |
|                 Paul
 | |
|                 <span class="radio"><input id="id_beatles_1" name="beatles" type="radio" value="paul" required></span>
 | |
|             </label>
 | |
|             <label for="id_beatles_2">
 | |
|                 George
 | |
|                 <span class="radio"><input id="id_beatles_2" name="beatles" type="radio" value="george" required></span>
 | |
|             </label>
 | |
|             <label for="id_beatles_3">
 | |
|                 Ringo
 | |
|                 <span class="radio"><input id="id_beatles_3" name="beatles" type="radio" value="ringo" required></span>
 | |
|             </label>
 | |
|         </fieldset>
 | |
| 
 | |
|     If you decide not to loop over the radio buttons -- e.g., if your template
 | |
|     includes ``{{ myform.beatles }}`` -- they'll be output in a ``<div>`` with
 | |
|     ``<div>`` tags, as above.
 | |
| 
 | |
|     The outer ``<div>`` container receives the ``id`` attribute of the widget,
 | |
|     if defined, or :attr:`BoundField.auto_id` otherwise.
 | |
| 
 | |
|     When looping over the radio buttons, the ``label`` and ``input`` tags include
 | |
|     ``for`` and ``id`` attributes, respectively. Each radio button has an
 | |
|     ``id_for_label`` attribute to output the element's ID.
 | |
| 
 | |
| ``CheckboxSelectMultiple``
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: CheckboxSelectMultiple
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/checkbox_select.html'``
 | |
|     * ``option_template_name``: ``'django/forms/widgets/checkbox_option.html'``
 | |
| 
 | |
|     Similar to :class:`SelectMultiple`, but rendered as a list of checkboxes:
 | |
| 
 | |
|     .. code-block:: html
 | |
| 
 | |
|         <div>
 | |
|           <div><input type="checkbox" name="..." ></div>
 | |
|           ...
 | |
|         </div>
 | |
| 
 | |
|     The outer ``<div>`` container receives the ``id`` attribute of the widget,
 | |
|     if defined, or :attr:`BoundField.auto_id` otherwise.
 | |
| 
 | |
| Like :class:`RadioSelect`, you can loop over the individual checkboxes for the
 | |
| widget's choices. Unlike :class:`RadioSelect`, the checkboxes won't include the
 | |
| ``required`` HTML attribute if the field is required because browser validation
 | |
| would require all checkboxes to be checked instead of at least one.
 | |
| 
 | |
| When looping over the checkboxes, the ``label`` and ``input`` tags include
 | |
| ``for`` and ``id`` attributes, respectively. Each checkbox has an
 | |
| ``id_for_label`` attribute to output the element's ID.
 | |
| 
 | |
| .. _file-upload-widgets:
 | |
| 
 | |
| File upload widgets
 | |
| -------------------
 | |
| 
 | |
| ``FileInput``
 | |
| ~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: FileInput
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/file.html'``
 | |
|     * Renders as: ``<input type="file" ...>``
 | |
| 
 | |
| ``ClearableFileInput``
 | |
| ~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: ClearableFileInput
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/clearable_file_input.html'``
 | |
|     * Renders as: ``<input type="file" ...>`` with an additional checkbox
 | |
|       input to clear the field's value, if the field is not required and has
 | |
|       initial data.
 | |
| 
 | |
| .. _composite-widgets:
 | |
| 
 | |
| Composite widgets
 | |
| -----------------
 | |
| 
 | |
| ``MultipleHiddenInput``
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: MultipleHiddenInput
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/multiple_hidden.html'``
 | |
|     * Renders as: multiple ``<input type="hidden" ...>`` tags
 | |
| 
 | |
|     A widget that handles multiple hidden widgets for fields that have a list
 | |
|     of values.
 | |
| 
 | |
| ``SplitDateTimeWidget``
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: SplitDateTimeWidget
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/splitdatetime.html'``
 | |
| 
 | |
|     Wrapper (using :class:`MultiWidget`) around two widgets: :class:`DateInput`
 | |
|     for the date, and :class:`TimeInput` for the time. Must be used with
 | |
|     :class:`SplitDateTimeField` rather than :class:`DateTimeField`.
 | |
| 
 | |
|     ``SplitDateTimeWidget`` has several optional arguments:
 | |
| 
 | |
|     .. attribute:: SplitDateTimeWidget.date_format
 | |
| 
 | |
|         Similar to :attr:`DateInput.format`
 | |
| 
 | |
|     .. attribute:: SplitDateTimeWidget.time_format
 | |
| 
 | |
|         Similar to :attr:`TimeInput.format`
 | |
| 
 | |
|     .. attribute:: SplitDateTimeWidget.date_attrs
 | |
|     .. attribute:: SplitDateTimeWidget.time_attrs
 | |
| 
 | |
|         Similar to :attr:`Widget.attrs`. A dictionary containing HTML
 | |
|         attributes to be set on the rendered :class:`DateInput` and
 | |
|         :class:`TimeInput` widgets, respectively. If these attributes aren't
 | |
|         set, :attr:`Widget.attrs` is used instead.
 | |
| 
 | |
| ``SplitHiddenDateTimeWidget``
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: SplitHiddenDateTimeWidget
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/splithiddendatetime.html'``
 | |
| 
 | |
|     Similar to :class:`SplitDateTimeWidget`, but uses :class:`HiddenInput` for
 | |
|     both date and time.
 | |
| 
 | |
| ``SelectDateWidget``
 | |
| ~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| .. class:: SelectDateWidget
 | |
| 
 | |
|     * ``template_name``: ``'django/forms/widgets/select_date.html'``
 | |
| 
 | |
|     Wrapper around three :class:`~django.forms.Select` widgets: one each for
 | |
|     month, day, and year.
 | |
| 
 | |
|     Takes several optional arguments:
 | |
| 
 | |
|     .. attribute:: SelectDateWidget.years
 | |
| 
 | |
|         An optional list/tuple of years to use in the "year" select box.
 | |
|         The default is a list containing the current year and the next 9 years.
 | |
| 
 | |
|     .. attribute:: SelectDateWidget.months
 | |
| 
 | |
|         An optional dict of months to use in the "months" select box.
 | |
| 
 | |
|         The keys of the dict correspond to the month number (1-indexed) and
 | |
|         the values are the displayed months::
 | |
| 
 | |
|             MONTHS = {
 | |
|                 1: _("jan"),
 | |
|                 2: _("feb"),
 | |
|                 3: _("mar"),
 | |
|                 4: _("apr"),
 | |
|                 5: _("may"),
 | |
|                 6: _("jun"),
 | |
|                 7: _("jul"),
 | |
|                 8: _("aug"),
 | |
|                 9: _("sep"),
 | |
|                 10: _("oct"),
 | |
|                 11: _("nov"),
 | |
|                 12: _("dec"),
 | |
|             }
 | |
| 
 | |
|     .. attribute:: SelectDateWidget.empty_label
 | |
| 
 | |
|         If the :class:`~django.forms.DateField` is not required,
 | |
|         :class:`SelectDateWidget` will have an empty choice at the top of the
 | |
|         list (which is ``---`` by default). You can change the text of this
 | |
|         label with the ``empty_label`` attribute. ``empty_label`` can be a
 | |
|         ``string``, ``list``, or ``tuple``. When a string is used, all select
 | |
|         boxes will each have an empty choice with this label. If ``empty_label``
 | |
|         is a ``list`` or ``tuple`` of 3 string elements, the select boxes will
 | |
|         have their own custom label. The labels should be in this order
 | |
|         ``('year_label', 'month_label', 'day_label')``.
 | |
| 
 | |
|         .. code-block:: python
 | |
| 
 | |
|             # A custom empty label with string
 | |
|             field1 = forms.DateField(widget=SelectDateWidget(empty_label="Nothing"))
 | |
| 
 | |
|             # A custom empty label with tuple
 | |
|             field1 = forms.DateField(
 | |
|                 widget=SelectDateWidget(
 | |
|                     empty_label=("Choose Year", "Choose Month", "Choose Day"),
 | |
|                 ),
 | |
|             )
 |