======= 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 ````. 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 `. 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 ` 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 `` Url: Comment: 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) >>> f.as_table() Name: Url: Comment: 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 ` or :ref:`create a "media" property `. These methods involve somewhat advanced Python programming and are described in detail in the :doc:`Form Assets ` 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 ` 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') '' 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') '' >>> >>> name = forms.TextInput(attrs={'required': False}) >>> name.render('name', '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 ``