Widgets

Un widget es la representación de Django de un elemento de entrada HTML. El widget maneja la renderización del HTML y la extracción de datos desde un diccionario GET/POST correspondiente al widget.

El HTML generado por los widgets integrados utiliza sintaxis HTML5, dirigida a <!DOCTYPE html>. Por ejemplo, utiliza atributos booleanos como checked en lugar del estilo XHTML de checked='checked'.

Truco

Los widgets no deben confundirse con los campos de formulario . Los campos de formulario tratan la lógica de validación y se utilizan directamente en plantillas. Los widgets manejan la renderización del elemento de entrada HTML de formulario en la página web y la extracción de datos brutos enviados. Sin embargo, los widgets necesitan ser asignados a campos de formulario.

Los textos traducidos son:

Cuando especificas un campo en una forma, Django utilizará el widget predeterminado que es apropiado para el tipo de datos a ser mostrados. Para encontrar qué widget se utiliza en cada campo, consulta la documentación sobre fields-integrados.

Sin embargo, si deseas usar un widget diferente para un campo, puedes utilizar el argumento widget en la definición del campo. Por ejemplo:

from django import forms


class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField(widget=forms.Textarea)

Esto especificaría una forma con un comentario que utiliza un widget de texto más grande Textarea, en lugar del widget predeterminado TextInput.

Setting arguments for widgets

Muchos widgets tienen argumentos adicionales opcionales; se pueden establecer cuando se define el widget en el campo. En el ejemplo siguiente, la propiedad years está configurada para un 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,
    )

Consulta la documentación sobre widgets-integrados para obtener más información sobre qué widgets están disponibles y cuáles aceptan argumentos.

Widgets heredando del widget Select

Los widgets que heredan de el widget Select se ocupan de las opciones. Presentan al usuario con una lista de opciones para elegir. Los diferentes widgets presentan esta elección de manera diferente; el propio widget Select utiliza la representación HTML de lista <select> , mientras que RadioSelect utiliza botones de radio.

Los widgets Select se utilizan por defecto en los campos ChoiceField. Las opciones mostradas en el widget se heredan del campo ChoiceField y cambiar ChoiceField.choices actualizará Select.choices. Por ejemplo:

>>> 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')]

Los widgets que ofrecen un atributo choices pueden utilizarse con campos que no están basados en opciones – como un campo de tipo CharField – pero se recomienda utilizar un campo basado en ChoiceField cuando las opciones son inherentes al modelo y no solo al widget representativo.

Personalizando instancias de widgets

Cuando Django renderiza un widget como HTML, solo renderiza marcado muy mínimo - Django no agrega nombres de clase ni ningún otro atributo específico del widget. Esto significa que, por ejemplo, todos los widgets TextInput aparecerán igual en las páginas web.

Hay dos formas de personalizar widgets: por instancia de widget y por clase de widget.

Estilizando instancias de widgets

Si deseas que una instancia de widget se vea diferente a otra, necesitarás especificar atributos adicionales en el momento en que se crea la instancia del widget y se asigna a un campo de formulario (y quizá agregar algunas reglas a tus archivos CSS).

Por ejemplo, considere el siguiente formulario:

from django import forms


class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField()

Este formulario incluirá widgets TextInput para los campos nombre y comentario, y un widget URLInput para el campo url. Cada uno tiene una representación predeterminada - sin clase CSS ni atributos adicionales:

>>> 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>

En una página web real, probablemente querrás personalizar esto. Quizá desees un elemento de entrada más grande para el comentario y quizá desees que el widget “nombre” tenga alguna clase CSS especial. También es posible especificar el atributo “type” para utilizar un tipo de entrada HTML5 diferente. Para hacer esto, utilizas la argumento Widget.attrs cuando se crea el 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"}))

También puedes modificar un widget en la definición del formulario:

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")

Si el campo no se declara directamente en la forma (como los campos de modelo form), puedes utilizar el atributo Form.fields:

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 incluirá entonces las características adicionales en la salida renderizada:

>>> 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>

También puedes establecer el id HTML utilizando attrs. Consulta BoundField.id_for_label para un ejemplo.

Estilización de clases de widget

Con los widgets, es posible agregar activos (css y javascript) y personalizar más profundamente su apariencia y comportamiento.

En resumen, necesitarás subclonar el widget y ya sea definir una clase «Media» interna o crear una propiedad «media».

Estos métodos implican programación en Python avanzada y se describen con detalle en la guía de temas del Form Assets.

Clases base de widget

Las clases base de widget Widget y MultiWidget son subclonadas por todos los widgets integrados y pueden servir como fundamento para widgets personalizados.

Widget

class Widget(attrs=None)[fuente]

Esta clase abstracta no se puede renderizar, pero proporciona el atributo básico attrs. También puedes implementar o sobreescribir el método render() en widgets personalizados.

attrs

Un diccionario que contiene los atributos HTML a establecer en el widget renderizado.

>>> 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">'

Si asignas un valor de True o False a un atributo, se renderizará como un atributo booleano HTML5:

>>> 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">'
supports_microseconds

Un atributo que por defecto es True. Si se establece en False, la parte microsegundos de los valores datetime y time se establecerán en 0.

format_value(value)[fuente]

Limpia y devuelve un valor para su uso en el template del widget. El valor value no está garantizado que sea una entrada válida, por lo tanto las implementaciones de subclases deben programar defensivamente.

get_context(name, value, attrs)[fuente]

Devuelve un diccionario de valores para usar al renderizar el template del widget. Por defecto, el diccionario contiene una sola clave, 'widget', que es la representación en forma de diccionario del widget y contiene las siguientes claves:

  • 'nombre': El nombre del campo desde el argumento name.

  • 'is_hidden': Un booleano que indica si este widget está oculto o no.

  • 'requerido': Un booleano que indica si el campo para este widget es requerido o no.

  • 'valor': El valor devuelto por format_value().

  • 'attrs': Atributos HTML para establecer en el widget renderizado. La combinación del atributo attrs y el argumento attrs.

  • 'template_name': El valor de self.template_name.

Las clases Widget pueden proporcionar valores de contexto personalizados sobrescribiendo este método.

id_for_label(id_)[fuente]

Devuelve el atributo HTML ID de este widget para su uso por un <label>, dado el ID del campo. Devuelve una cadena vacía si no está disponible un ID.

Esta función es necesaria porque algunos widgets tienen múltiples elementos HTML y, por lo tanto, múltiples IDs. En ese caso, este método debe devolver un valor de ID que corresponda al primer ID en las etiquetas del widget.

render(name, value, attrs=None, renderer=None)[fuente]

Renderea un widget a HTML utilizando el renderizador dado. Si renderer es None, se utiliza el renderizador desde la configuración FORM_RENDERER.

value_from_datadict(data, files, name)[fuente]

Dado un diccionario de datos y el nombre de este widget, devuelve el valor de este widget. Los files pueden contener datos provenientes del request.FILES. Devuelve None si no se proporcionó un valor. Tenga en cuenta también que value_from_datadict puede llamarse más de una vez durante el manejo de los datos de formulario, por lo que si la personalizas y agregas procesamiento costoso, debes implementar algún mecanismo de caché tú mismo.

value_omitted_from_data(data, files, name)[fuente]

Dado los diccionarios data y files y el nombre de este widget, devuelve si hay datos o archivos para el widget.

El resultado del método afecta si un campo en una forma de modelo regresa a su valor por defecto.

Los casos especiales son CheckboxInput, CheckboxSelectMultiple y SelectMultiple, que siempre devuelven False porque un checkbox no marcado y una <select multiple> no seleccionada no aparecen en los datos de la solicitud HTML, por lo tanto es desconocido si el usuario envió un valor.

use_fieldset

Un atributo para identificar si el widget debe agruparse en un <fieldset> con un <legend> cuando se renderice. Por defecto es False, pero es True cuando el widget contiene múltiples etiquetas <input>, como CheckboxSelectMultiple, RadioSelect, MultiWidget, SplitDateTimeWidget y SelectDateWidget.

use_required_attribute(initial)[fuente]

Dado el valor inicial de un campo de formulario initial, devuelve si el widget puede ser renderizado con la atributo HTML required. Las formas utilizan este método junto con Field.required y Form.use_required_attribute para determinar si mostrar o no el atributo required para cada campo.

Por defecto, devuelve False para los widgets ocultos y True en caso contrario. Los casos especiales son FileInput y ClearableFileInput, que devuelven False cuando initial está establecido, y CheckboxSelectMultiple, que siempre devuelve False porque la validación del navegador requeriría que todas las casillas de verificación estén seleccionadas en lugar de al menos una.

Sobreescribe este método en widgets personalizados que no sean compatibles con la validación del navegador. Por ejemplo, un widget de editor de texto WSYSIWG respaldado por un elemento textarea oculto puede querer devolver siempre False para evitar la validación del navegador en el campo oculto.

MultiWidget

class MultiWidget(widgets, attrs=None)[fuente]

Un widget compuesto por múltiples widgets. MultiWidget funciona de la mano con la clase MultiValueField.

MultiWidget tiene un argumento requerido:

widgets

Una secuencia conteniendo los widgets necesarios. Por ejemplo:

>>> 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">'

Puedes proporcionar un diccionario para especificar sufijos personalizados para el atributo name en cada subwidget. En este caso, para cada par (clave, widget), la clave se agregará al nombre del widget para generar el valor de atributo. Puedes proporcionar la cadena vacía ('') para una sola clave, con el fin de suprimir el sufijo para un widget. Por ejemplo:

>>> 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">'

Y un método requerido:

decompress(value)[fuente]

Este método toma un valor «comprimido» de la campo y devuelve una lista de valores «descompresos». El valor de entrada se puede suponer válido, pero no necesariamente no vacío.

Este método debe ser implementado por la subclase, y dado que el valor puede estar vacío, la implementación debe ser defensiva.

La razón detrás de la «descompresión» es que es necesario «dividir» el valor combinado del campo de formulario en los valores para cada widget.

Un ejemplo de esto es cómo SplitDateTimeWidget convierte un valor de tipo datetime en una lista con fecha y hora separadas en dos valores distintos:

from django.forms import MultiWidget


class SplitDateTimeWidget(MultiWidget):
    # ...

    def decompress(self, value):
        if value:
            return [value.date(), value.time()]
        return [None, None]

Truco

Ten en cuenta que la clase ~django.forms.MultiValueField tiene un método complementario compress <compress> con la responsabilidad opuesta: combinar los valores limpiados de todos los campos miembros en uno.

Proporciona algún contexto personalizado:

get_context(name, value, attrs)[fuente]

Además de la clave widget descrita en Widget.get_context(), MultiWidget agrega una clave widget[“subwidgets”].

Estos pueden ser recorridos en la plantilla del widget:

{% for subwidget in widget.subwidgets %}
    {% include subwidget.template_name with widget=subwidget %}
{% endfor %}

Aquí tienes un ejemplo de widget que hereda de MultiWidget para mostrar una fecha con el día, mes y año en diferentes cajas de selección. Este widget está destinado a ser utilizado con un DateField más que con un MultiValueField, por lo tanto hemos implementado 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)

El constructor crea varias instancias de Select en una lista. El método super() utiliza esta lista para configurar el widget.

El método requerido decompress() descompone un valor de tipo datetime.date en los valores correspondientes a día, mes y año para cada widget. Si se seleccionó una fecha inválida, como el 30 de febrero (que no existe), el campo DateField pasa este método una cadena en lugar de los valores individuales, por lo que necesita ser parseada. El return final maneja el caso en el que value es None, lo que significa que no tenemos ningún valor predeterminado para nuestros subwidgets.

La implementación predeterminada del método value_from_datadict() devuelve una lista de valores correspondientes a cada widget. Esto es apropiado cuando se utiliza un widget MultiWidget con un campo MultiValueField. Pero ya que queremos utilizar este widget con un campo DateField, que acepta un valor único, hemos sobrescrito este método. La implementación aquí combina los datos de los subwidgets en una cadena en el formato que espera el campo DateField.

Widgets integrados

Django proporciona representaciones de todos los widgets HTML básicos, más algunos grupos comunes de widgets en el módulo django.forms.widgets, incluyendo la entrada de texto, varios controles y selectores, subida de archivos y manejo de entradas múltiples.

Widgets que manejan la entrada de texto

Estos widgets utilizan los elementos HTML input y textarea.

TextInput

class TextInput[fuente]
  • input_type: 'text'

  • template_name: 'django/forms/widgets/text.html'

  • Se renderiza como: <input type="text" ...>

NumberInput

class NumberInput[fuente]
  • tipo_de_entrada: 'number'

  • nombre_de_plantilla: 'django/forms/widgets/number.html'

  • Se renderiza como: <input type="number" ...>

Ten en cuenta que no todos los navegadores admiten la entrada de números locales en tipos de entrada number. Django evita utilizarlos para campos cuya propiedad localize esté configurada a True.

EmailInput

class EmailInput[fuente]
  • tipo_de_entrada: 'email'

  • nombre_de_plantilla: 'django/forms/widgets/email.html'

  • Se renderiza como: <input type="email" ...>

URLInput

class URLInput[fuente]
  • El texto traducido es:

  • template_name: 'django/forms/widgets/url.html'

  • Se renderiza como: <input type="url" ...>

ColorInput

class ColorInput[fuente]
  • input_type: 'color'

  • template_name: 'django/forms/widgets/color.html'

  • Se renderiza como: <input type="color" ...>

SearchInput

class SearchInput[fuente]
  • input_type: 'search'

  • template_name: 'django/forms/widgets/search.html'

  • Los textos traducidos son:

TelInput

class TelInput[fuente]
  • input_type: 'tel'

  • template_name: 'django/forms/widgets/tel.html'

  • Renders as: <input type="tel" ...>

Los navegadores no realizan validación en el lado del cliente por defecto porque los formatos de números telefónicos varían mucho alrededor del mundo. Puedes agregar algunas mediante la configuración de pattern, minlength o maxlength en el argumento Widget.attrs.

Además, puedes agregar validación en el lado del servidor a tu campo de formulario con un validador como RegexValidator o a través de paquetes terceros, como django-phonenumber-field.

PasswordInput

class PasswordInput[fuente]
  • input_type: 'password'

  • template_name: 'django/forms/widgets/password.html'

  • Los campos de texto se renderizan como: <input type="password" ...>

Toma un argumento opcional:

render_value

Determina si el widget tendrá un valor rellenado cuando la forma sea reexibida después de un error de validación (el valor por defecto es False).

HiddenInput

class HiddenInput[fuente]
  • input_type: 'hidden'

  • template_name: 'django/forms/widgets/hidden.html'

  • Los campos de texto se renderizan como: <input type="hidden" ...>

Ten en cuenta que también existe el widget MultipleHiddenInput que encapsula un conjunto de elementos de entrada ocultos.

DateInput

class DateInput[fuente]
  • input_type: 'text'

  • template_name: 'django/forms/widgets/date.html'

  • Se renderiza como: <input type="text" ...>

Toma los mismos argumentos que TextInput, con un argumento adicional opcional:

format

El formato en el que se mostrará el valor inicial de este campo.

Si no se proporciona la argumento format, el formato por defecto es el primer formato encontrado en DATE_INPUT_FORMATS y respeta Format localization. Los formatos %U, %W y %j no están soportados por este widget.

DateTimeInput

class DateTimeInput[fuente]
  • input_type: 'text'

  • template_name: 'django/forms/widgets/datetime.html'

  • Se renderiza como: <input type="text" ...>

Toma los mismos argumentos que TextInput, con un argumento adicional opcional:

format

El formato en el que se mostrará el valor inicial de este campo.

Si no se proporciona la argumento format, el formato por defecto es el primer formato encontrado en DATETIME_INPUT_FORMATS y respeta Format localization. Los formatos %U, %W y %j no están soportados por este widget.

Por defecto, la parte de microsegundos del valor de tiempo siempre se establece en 0. Si se requieren microsegundos, utilice una subclase con el atributo supports_microseconds establecido en True.

TimeInput

class TimeInput[fuente]
  • input_type: 'text'

  • template_name: 'django/forms/widgets/time.html'

  • Se renderiza como: <input type="text" ...>

Toma los mismos argumentos que TextInput, con un argumento adicional opcional:

format

El formato en el que se mostrará el valor inicial de este campo.

Si no se proporciona la argumento format, el formato por defecto es el primer formato encontrado en TIME_INPUT_FORMATS y respeta Format localization.

Para el tratamiento de microsegundos, consulte DateTimeInput.

Caja de texto

class Textarea[fuente]
  • nombre_de_plantilla: 'django/forms/widgets/textarea.html'

  • Se renderiza como: <textarea>...</textarea>

Selector y widgets de casilla de verificación

Estos widgets utilizan los elementos HTML <select>, <input type="checkbox">, y <input type="radio">.

Los widgets que renderizan múltiples opciones tienen un atributo option_template_name que especifica la plantilla utilizada para renderizar cada opción. Por ejemplo, para el widget Select, select_option.html renderiza el <option> para un <select>.

CheckboxInput

class CheckboxInput[fuente]
  • tipo_de_entrada: 'checkbox'

  • nombre_de_plantilla: 'django/forms/widgets/checkbox.html'

  • Se renderiza como: <input type="checkbox" ...>

Toma un argumento opcional:

check_test

Un callable que tome el valor de la CheckboxInput y devuelva True si el cuadro de verificación debe estar marcado para ese valor.

Select

class Select[fuente]
  • template_name: 'django/forms/widgets/select.html'

  • option_template_name: 'django/forms/widgets/select_option.html'

  • Se renderiza como: <select><option ...>...</select>

choices

Esta atributo es opcional cuando el campo de formulario no tiene un atributo choices. Si lo tiene, sobreescribirá cualquier cosa que establezcas aquí cuando el atributo se actualice en el Field.

NullBooleanSelect

class NullBooleanSelect[fuente]
  • template_name: 'django/forms/widgets/select.html'

  • option_template_name: 'django/forms/widgets/select_option.html'

Widget de selección con opciones “Desconocido”, “Sí” y “No”

SelectMultiple

class SelectMultiple[fuente]
  • template_name: 'django/forms/widgets/select.html'

  • option_template_name: 'django/forms/widgets/select_option.html'

Similar a Select, pero permite la selección múltiple: <select multiple>...</select>

RadioSelect

class RadioSelect[fuente]
  • template_name: 'django/forms/widgets/radio.html'

  • option_template_name: 'django/forms/widgets/radio_option.html'

Similar a Select, pero renderizado como una lista de botones de radio dentro de etiquetas <div>:

<div>
  <div><input type="radio" name="..."></div>
  ...
</div>

Para tener un control más detallado sobre la marca de código generada, puedes recorrer los botones de radio en el template. Asumiendo que tienes un formulario myform con un campo beatles que utiliza a RadioSelect como widget:

<fieldset>
    <legend>{{ myform.beatles.label }}</legend>
    {% for radio in myform.beatles %}
    <div class="myradio">
        {{ radio }}
    </div>
    {% endfor %}
</fieldset>

Esto generarían la siguiente marca de código 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>

Que incluye las etiquetas <label>. Para tener un control más detallado, puedes utilizar los atributos tag, choice_label y id_for_label de cada botón de radio. Por ejemplo, este template…

<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>

…resultaría en la siguiente marca de código 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>

Si decides no recorrer los botones de radio – por ejemplo, si tu template incluye {{ myform.beatles }} – se mostrarán dentro de un contenedor <div> con etiquetas <div>, como arriba.

El contenedor <div> exterior recibe el atributo id del widget, si está definido, o BoundField.auto_id en caso contrario.

Cuando se itera sobre los botones de radio, las etiquetas label y input incluyen atributos for y id, respectivamente. Cada botón de radio tiene un atributo id_for_label para emitir el ID del elemento.

CheckboxSelectMultiple

class CheckboxSelectMultiple[fuente]
  • template_name: 'django/forms/widgets/checkbox_select.html'

  • option_template_name: 'django/forms/widgets/checkbox_option.html'

Similar a SelectMultiple, pero renderizado como una lista de casillas de verificación:

<div>
  <div><input type="checkbox" name="..." ></div>
  ...
</div>

El contenedor <div> exterior recibe el atributo id del widget, si está definido, o BoundField.auto_id en caso contrario.

Al igual que RadioSelect, puedes iterar sobre las casillas individuales para las opciones del widget. A diferencia de RadioSelect, las casillas de verificación no incluirán el atributo HTML required si el campo es requerido, ya que la validación en el navegador requeriría que todas las casillas estuvieran seleccionadas en lugar de al menos una.

Cuando se itera sobre las casillas de verificación, las etiquetas label y input incluyen atributos for y id, respectivamente. Cada casilla de verificación tiene un atributo id_for_label para emitir el ID del elemento.

Widgets de carga de archivos

CheckboxSelectMultiple

class FileInput[fuente]
  • template_name: 'django/forms/widgets/file.html'

  • Los textos traducidos son:

Input de archivo claro

class ClearableFileInput[fuente]
  • template_name: 'django/forms/widgets/clearable_file_input.html'

  • Los renderiza como: <input type="file" ...> con un input de casilla adicional para borrar el valor del campo, si el campo no es obligatorio y tiene datos iniciales.

Widgets compuestos

Input oculto múltiple

class MultipleHiddenInput[fuente]
  • template_name: 'django/forms/widgets/multiple_hidden.html'

  • Se renderiza como varias etiquetas <input type="hidden" ...>.

Un widget que maneja varios widgets ocultos para campos que tienen una lista de valores.

Widget de fecha y hora dividida

class SplitDateTimeWidget[fuente]
  • template_name: 'django/forms/widgets/splitdatetime.html'

Envoltura (utilizando MultiWidget) alrededor de dos widgets: DateInput para la fecha, y TimeInput para la hora. Debe usarse con SplitDateTimeField en lugar de DateTimeField.

SplitDateTimeWidget tiene varias argumentos opcionales:

date_format

Similar a DateInput.format

time_format

Similar a TimeInput.format

date_attrs
time_attrs

Similar a Widget.attrs. Un diccionario que contiene atributos HTML para ser establecidos en los widgets de fecha y hora renderizados, respectivamente. Si no se establecen estos atributos, se utiliza Widget.attrs en su lugar.

SplitHiddenDateTimeWidget

class SplitHiddenDateTimeWidget[fuente]
  • template_name: 'django/forms/widgets/splithiddendatetime.html'

Similar a SplitDateTimeWidget, pero utiliza HiddenInput para tanto la fecha como la hora.

SelectDateWidget

class SelectDateWidget[fuente]
  • template_name: “django/forms/widgets/select_date.html”

Un contenedor alrededor de tres widgets Select: uno para cada mes, día y año.

Toma varios argumentos opcionales:

years

Una lista/tupla opcional de años a utilizar en la caja selectiva del «año». El valor por defecto es una lista que contiene el año actual y los siguientes 9 años.

months

Un diccionario opcional de meses a utilizar en la caja selectiva de «meses».

Las claves del diccionario corresponden al número de mes (1-índice) y los valores son los meses que se muestran:

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"),
}
empty_label

Si el campo DateField no es requerido, SelectDateWidget tendrá una elección vacía en la parte superior de la lista (que es --- por defecto). Puedes cambiar el texto de esta etiqueta con la propiedad empty_label. empty_label puede ser un string, list o tuple. Cuando se utiliza un string, todas las cajas selectivas tendrán una elección vacía con este etiquetado. Si empty_label es una lista o tupla de 3 elementos de cadena, las cajas selectivas tendrán su propio etiquetado personalizado. Los etiquetados deben estar en este orden ('year_label', 'month_label', 'day_label').

# 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"),
    ),
)