---
title: "Composants de formulaires (« widgets »)"
version: 1.9
locale: fr
source: https://docs.djangoproject.com/fr/1.9/ref/forms/widgets/
canonical: https://djangodocs.dev/fr/1.9/ref/forms/widgets/
---
# Composants de formulaires (« widgets »)

Un composant de formulaire est la représentation Django d’un élément de saisie HTML. Le composant se charge de produire le code HTML et d’extraire les données qui lui sont propres dans un dictionnaire GET/POST.

> **Tip**
>
> Il ne faut pas confondre les composants avec les [champs de formulaires](/fr/1.9/ref/forms/fields/). Ces derniers se chargent de la logique de validation de la saisie et sont directement utilisés dans les gabarits. Les composants de formulaires s’occupent de produire le code HTML des éléments de saisie de formulaire dans les pages Web ainsi que de l’extraction de données brutes envoyées. Cependant, les composants de formulaires doivent être [attribués](#widget-to-field) aux champs de formulaires.

## Définition des composants

Chaque fois que vous définissez un champ de formulaire, Django utilise un composant par défaut correspondant au type de donnée qui doit être affiché. Pour savoir quel composant est utilisé pour quel champ, consultez la documentation au sujet des [champs intégrés](/fr/1.9/ref/forms/fields/#built-in-fields).

Cependant, si vous souhaitez utiliser un autre composant pour un champ, il suffit d’utiliser le paramètre [`widget`](/fr/1.9/ref/forms/fields/#django.forms.Field.widget) dans la définition du champ. Par exemple :

```
from django import forms

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

Ce code définit un formulaire avec un champ de commentaires utilisant un composant [`Textarea`](#django.forms.Textarea) plus grand, plutôt que le composant [`TextInput`](#django.forms.TextInput) par défaut.

## Définition de paramètres pour les composants

Beaucoup de composants acceptent des paramètres supplémentaires facultatifs ; ils peuvent être définis lors de l’attribution du composant au champ de formulaire. Dans l’exemple suivant, l’attribut [`years`](#django.forms.SelectDateWidget.years) est défini pour un composant [`SelectDateWidget`](#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,
    )
```

Consultez les [composants de formulaires intégrés](#built-in-widgets) pour plus d’informations sur les composants disponibles et les paramètres acceptés.

## Composants héritant du composant `Select`

Les composants héritant du composant [`Select`](#django.forms.Select) gèrent des choix. Ils offrent à l’utilisateur une liste d’options à choix. Les différents composants présentent ces choix différemment ; le composant [`Select`](#django.forms.Select) utilise lui-même une représentation en liste HTML `<select>`, alors que [`RadioSelect`](#django.forms.RadioSelect) utilise des boutons radio.

Les composants [`Select`](#django.forms.Select) sont utilisés par défaut pour les champs [`ChoiceField`](/fr/1.9/ref/forms/fields/#django.forms.ChoiceField). Les choix affichés dans le composant sont hérités de [`ChoiceField`](/fr/1.9/ref/forms/fields/#django.forms.ChoiceField), ce qui fait qu’en modifiant [`ChoiceField.choices`](/fr/1.9/ref/forms/fields/#django.forms.ChoiceField.choices), les choix disponibles dans [`Select.choices`](#django.forms.Select.choices) sont mis à jour. Par exemple :

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

Les composants possédant un attribut [`choices`](#django.forms.Select.choices) peuvent toutefois être utilisés avec des champs qui ne sont pas basés sur des choix, comme par exemple [`CharField`](/fr/1.9/ref/forms/fields/#django.forms.CharField), mais il est recommandé d’utiliser plutôt un champ basé sur [`ChoiceField`](/fr/1.9/ref/forms/fields/#django.forms.ChoiceField) lorsque les choix sont inhérents au modèle et pas simplement une manière d’afficher un composant.

## Personnalisation des instances de composants

Lorsque Django affiche un composant en HTML, le balisage est minimal - Django n’ajoute ni nom de classe, ni d’autres attributs spécifiques au composant. Cela signifie que par exemple tous les composants [`TextInput`](#django.forms.TextInput) ont la même apparence sur les pages Web.

Il y a deux manières de personnaliser des composants : [par instance de composant](#styling-widget-instances) et [par classe de composant](#styling-widget-classes).

### Ajout de styles aux instances de composants

Si vous souhaitez qu’une instance de composant apparaisse différemment d’une autre instance, il sera nécessaire d’indiquer des attributs supplémentaires au moment où l’objet composant est instancié et qu’il est attribué à un champ de formulaire (ce qui n’empêche pas d’ajouter aussi certaines règles dans vos fichiers CSS).

Par exemple, en prenant l’exemple de ce formulaire simple :

```
from django import forms

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

Ce formulaire inclut trois composants [`TextInput`](#django.forms.TextInput) par défaut, avec le rendu HTML par défaut – pas de classe CSS, pas d’attribut supplémentaire. Cela signifie que les zones de saisie présentées par chaque composant seront affichées exactement de la même manière :

```
>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
<tr><th>Url:</th><td><input type="url" name="url"/></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
```

Sur une page Web réelle, il est souvent souhaitable d’afficher les composants de manière différente. Le champ commentaire pourrait nécessiter une plus grande zone de saisie, et le composant « name » pourrait être complété par une classe CSS spécifique. Il est aussi possible de définir l’attribut « type » pour profiter des nouveaux types de composants HTML5. Pour cela, utilisez le paramètre [`Widget.attrs`](#django.forms.Widget.attrs) lors de la création du composant :

```
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'}))
```

Django se chargera ensuite d’inclure les attributs supplémentaires dans le résultat affiché :

```
>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
<tr><th>Url:</th><td><input type="url" name="url"/></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
```

Vous pouvez également définir l’attribut HTML `id` à l’aide de [`attrs`](#django.forms.Widget.attrs). Voir [`BoundField.id_for_label`](/fr/1.9/ref/forms/api/#django.forms.BoundField.id_for_label) pour un exemple.

### Ajout de styles aux classes de composants

Avec les composants, il est possible d’adjoindre des ressources (`css` et `javascript`) et de personnaliser plus encore leur apparence et leur comportement.

Rapidement dit, il est nécessaire de créer une sous-classe du composant et de soit [définir une classe internet « Media »](/fr/1.9/topics/forms/media/#assets-as-a-static-definition) ou de [créer une propriété « media »](/fr/1.9/topics/forms/media/#dynamic-property).

Ces méthodes impliquent une utilisation relativement avancée de la programmation Python et sont décrites en détails dans le guide thématique des [fichiers annexes de formulaires](/fr/1.9/topics/forms/media/).

## Classes `Widget` de base

Les classes basiques de composants [`Widget`](#django.forms.Widget) et [`MultiWidget`](#django.forms.MultiWidget) sont héritées par tous les [composants intégrés](#built-in-widgets) et peuvent servir de fondement pour des composants personnalisés.

### `Widget`

#### `class Widget(attrs=None)`

Cette classe abstraite ne peut pas être affichée telle quelle, mais elle fournit l’attribut de base [`attrs`](#django.forms.Widget.attrs). Vous pouvez aussi implémenter ou surcharger la méthode [`render()`](#django.forms.Widget.render) dans des composants personnalisés.

#### `attrs`

Un dictionnaire contenant les attributs HTML à définir pour le composant affiché.

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

> **Changed in Django 1.8**
>
> Si vous attribuez une valeur `True` ou `False` à un attribut, il sera généré comme un attribut HTML5 booléen :
>
> ```
> >>> 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 attribut qui vaut `True` par défaut. Si la valeur est `False`, les microsecondes faisant partie des valeurs [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime) et [`time`](https://docs.python.org/3/library/datetime.html#datetime.time) sont mises à `0`.

> **New in Django 1.9**
>
> Dans les anciennes versions, cet attribut n’était défini que pour les composants date et heure (valait `False`).

#### `id_for_label(self, id_)`

Renvoie l’attribut HTML `id` de ce composant à l’usage de la balise `<label>`, en fonction de l’attribut `id` du champ. Renvoie `None` si `id` n’est pas disponible.

Ce point d’entrée est nécessaire car certains composants possèdent plusieurs éléments HTML et donc plusieurs `id`. Dans ce cas, cette méthode doit renvoyer une valeur `id` qui correspond au premier `id` dans les balises du composant.

#### `render(name, value, attrs=None)`

Renvoie le code HTML du composant, sous forme de chaîne Unicode. Cette méthode doit être implémentée par la sous-classe, sous peine d’obtenir une exception `NotImplementedError`.

Il n’est pas certain que aa valeur « value » donnée soit une saisie valide, il faut donc que les implémentations des sous-classes programment défensivement.

#### `value_from_datadict(data, files, name)`

Étant donné un dictionnaire de données et le nom de ce composant, renvoie la valeur de ce composant. `files` peut contenir des données provenant de [`request.FILES`](/fr/1.9/ref/request-response/#django.http.HttpRequest.FILES). Renvoie `None` si aucune valeur n’a été fournie. Notez également que `value_from_datadict` peut être appelée plus d’une fois durant le traitement des données de formulaire, ce qui fait que si vous la personnalisez et que vous y effectuez un traitement lourd, il est recommandé de mettre en place un mécanisme de cache.

### `MultiWidget`

#### `class MultiWidget(widgets, attrs=None)`

Un composant formé de plusieurs composants. [`MultiWidget`](#django.forms.MultiWidget) fonctionne de concert avec le champ [`MultiValueField`](/fr/1.9/ref/forms/fields/#django.forms.MultiValueField).

[`MultiWidget`](#django.forms.MultiWidget) requiert un paramètre :

#### `widgets`

Un objet itérable contenant les composants nécessaires.

Ainsi qu’une méthode obligatoire :

#### `decompress(value)`

Cette méthode accepte une seule valeur « compressée » à partir du champ et renvoie une liste de valeurs « décompressées ». La valeur d’entrée peut être considérée comme valide, mais pourrait être vide.

Cette méthode **doit être implémentée** par la sous-classe, et comme la valeur peut être vide, l’implémentation doit être défensive.

La logique de la « décompression » est qu’il est nécessaire de « scinder » la valeur combinée du champ de formulaire en valeurs distinctes pour chaque composant.

Un exemple pour illustrer ce processus est la façon dont [`SplitDateTimeWidget`](#django.forms.SplitDateTimeWidget) transforme une valeur [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime) en une liste où la date et l’heure sont séparées :

```
from django.forms import MultiWidget

class SplitDateTimeWidget(MultiWidget):

    # ...

    def decompress(self, value):
        if value:
            return [value.date(), value.time().replace(microsecond=0)]
        return [None, None]
```

> **Tip**
>
> Notez que [`MultiValueField`](/fr/1.9/ref/forms/fields/#django.forms.MultiValueField) possède une méthode complémentaire [`compress()`](/fr/1.9/ref/forms/fields/#django.forms.MultiValueField.compress) qui joue le rôle inverse, combiner les valeurs nettoyées de tous les sous-composants en une seule valeur.

Voici quelques autres méthodes dont la surcharge peut être utile :

#### `render(name, value, attrs=None)`

Le paramètre `value` est traité différemment dans cette méthode que pour les autres sous-classes de [`Widget`](#django.forms.Widget) parce qu’il s’agit de trouver comment scinder une valeur unique qui doit être affichée dans plusieurs composants.

Le paramètre `value` utilisé lors de l’affichage peut se trouver sous deux formes :

- Un objet `list`.
- Une valeur unique (c’est-à-dire une chaîne) représentant la version « compressée » d’une liste de valeurs.

Si `value` est une liste, le résultat de [`render()`](#django.forms.MultiWidget.render) sera une concaténation de l’affichage des composants enfants. Si `value` n’est pas une liste, elle sera d’abord traitée par la méthode [`decompress()`](#django.forms.MultiWidget.decompress) pour créer la liste avant de procéder à l’affichage.

Lorsque `render()` effectue l’affichage HTML, chaque valeur de la liste est affichée avec le composant correspondant, – la première valeur est produite avec le premier composant, la deuxième valeur est produite avec le deuxième composant, etc.

Au contraire de ce qui se passe avec les composants à valeur unique, la méthode [`render()`](#django.forms.MultiWidget.render) n’a pas besoin d’être implémentée par les sous-classes.

#### `format_output(rendered_widgets)`

Étant donné une liste des composants affichés (sous forme de chaînes), renvoie une chaîne Unicode représentant le code HTML de l’ensemble.

Ce point d’entrée permet de mettre en forme la disposition HTML des composants selon vos besoins.

Voici un exemple de composant héritant de [`MultiWidget`](#django.forms.MultiWidget) qui affiche une date avec le jour, le mois et l’année dans des listes déroulantes différentes. Ce composant est prévu pour être utilisé avec un champ [`DateField`](/fr/1.9/ref/forms/fields/#django.forms.DateField) plutôt qu’avec un [`MultiValueField`](/fr/1.9/ref/forms/fields/#django.forms.MultiValueField), c’est pourquoi nous avons implémenté [`value_from_datadict()`](#django.forms.Widget.value_from_datadict):

```
from datetime import date
from django.forms import widgets

class DateSelectorWidget(widgets.MultiWidget):
    def __init__(self, attrs=None):
        # create choices for days, months, years
        # example below, the rest snipped for brevity.
        years = [(year, year) for year in (2011, 2012, 2013)]
        _widgets = (
            widgets.Select(attrs=attrs, choices=days),
            widgets.Select(attrs=attrs, choices=months),
            widgets.Select(attrs=attrs, choices=years),
        )
        super(DateSelectorWidget, self).__init__(_widgets, attrs)

    def decompress(self, value):
        if value:
            return [value.day, value.month, value.year]
        return [None, None, None]

    def format_output(self, rendered_widgets):
        return ''.join(rendered_widgets)

    def value_from_datadict(self, data, files, name):
        datelist = [
            widget.value_from_datadict(data, files, name + '_%s' % i)
            for i, widget in enumerate(self.widgets)]
        try:
            D = date(
                day=int(datelist[0]),
                month=int(datelist[1]),
                year=int(datelist[2]),
            )
        except ValueError:
            return ''
        else:
            return str(D)
```

Le constructeur crée plusieurs composants [`Select`](#django.forms.Select) dans un tuple. La classe `super` utilise ce tuple pour configurer le composant.

La méthode [`format_output()`](#django.forms.MultiWidget.format_output) est assez standard ici (c’est en fait la même que celle qui a été implémentée par défaut pour `MultiWidget`), mais l’idée est que vous puissiez ajouter du code HTML personnalisé entre les composants en cas de besoin.

La méthode obligatoire [`decompress()`](#django.forms.MultiWidget.decompress) partage une valeur `datetime.date` en valeurs distinctes de jour, mois et année correspondant à chaque composant. Notez la manière dont la méthode traite le cas où `value` vaut `None`.

Lîmplémentation par défaut de [`value_from_datadict()`](#django.forms.Widget.value_from_datadict) renvoie une liste de valeurs correspondant à chaque `Widget`. C’est le comportement correct lorsqu’un composant `MultiWidget` est utilisé de concert avec un champ [`MultiValueField`](/fr/1.9/ref/forms/fields/#django.forms.MultiValueField), mais comme nous voulons utiliser ce composant avec un champ [`DateField`](/fr/1.9/ref/forms/fields/#django.forms.DateField) qui n’accepte qu’une seule valeur, nous avons surchargé la méthode afin de combiner les données de tous les sous-composants en un objet `datetime.date`. La méthode extrait les données du dictionnaire `POST`, puis construit et valide la date. Si elle est valide, la date sous forme de chaîne est renvoyée ; sinon une chaîne vide est renvoyée, ce qui fera que `form.is_valid` renverra `False`.

## Composants intégrés

Dans son module `django.forms.widgets`, Django fournit une représentation de tous les composants HTML de base, plus certains groupes de composants fréquemment utilisés, y compris la [saisie de texte](#text-widgets), [diverses cases à cocher et listes à choix](#selector-widgets), l”[envoi de fichiers](#file-upload-widgets) et le [traitement de saisies à plusieurs valeurs](#composite-widgets).

### Composants chargés de la saisie de texte

Ces composants font usage des éléments HTML `input` et `textarea`.

#### `TextInput`

#### `class TextInput`

Zone de saisie de texte : `<input type="text" ...>`

#### `NumberInput`

#### `class NumberInput`

Zone de saisie de texte : `<input type="number" ...>`

Il faut savoir que certains navigateurs ne gèrent pas correctement la saisie de nombres régionalisés dans les types de zones `number`. Django lui-même évite de les utiliser pour les champs dont la propriété [`localize`](/fr/1.9/ref/forms/fields/#django.forms.Field.localize) est `True`.

#### `EmailInput`

#### `class EmailInput`

Zone de saisie de texte : `<input type="email" ...>`

#### `URLInput`

#### `class URLInput`

Zone de saisie de texte : `<input type="url" ...>`

#### `PasswordInput`

#### `class PasswordInput`

Saisie de mots de passe : `<input type='password' ...>`

Accepte un paramètre facultatif :

#### `render_value`

Détermine si le composant contient une valeur lorsque le formulaire est réaffiché après une erreur de validation (la valeur par défaut est `False`).

#### `HiddenInput`

#### `class HiddenInput`

Zone de saisie masquée : `<input type='hidden' ...>`

Notez qu’il existe également un composant [`MultipleHiddenInput`](#django.forms.MultipleHiddenInput) qui regroupe un ensemble de zones de saisie masquées.

#### `DateInput`

#### `class DateInput`

Saisie de date sous forme de zone de texte simple : `<input type='text' ...>`

Accepte les mêmes paramètres que [`TextInput`](#django.forms.TextInput), avec en plus un paramètre facultatif :

#### `format`

Le format dans lequel la valeur initiale du champ est affichée.

Si aucun paramètre `format` n’est indiqué, le format par défaut est le premier format trouvé dans [`DATE_INPUT_FORMATS`](/fr/1.9/ref/settings/#std-setting-DATE_INPUT_FORMATS) en respectant la [Régionalisation des formats](/fr/1.9/topics/i18n/formatting/).

#### `DateTimeInput`

#### `class DateTimeInput`

Saisie de date/heure sous forme de zone de texte simple : `<input type='text' ...>`

Accepte les mêmes paramètres que [`TextInput`](#django.forms.TextInput), avec en plus un paramètre facultatif :

#### `format`

Le format dans lequel la valeur initiale du champ est affichée.

Si aucun paramètre `format` n’est indiqué, le format par défaut est le premier format trouvé dans [`DATETIME_INPUT_FORMATS`](/fr/1.9/ref/settings/#std-setting-DATETIME_INPUT_FORMATS) en respectant la [Régionalisation des formats](/fr/1.9/topics/i18n/formatting/).

Par défaut, la partie microsecondes de la valeur de temps est toujours définie à `0`. Si les microsecondes sont nécessaires, créez une sous-classe avec l’attribut [`supports_microseconds`](#django.forms.Widget.supports_microseconds) défini à `True`.

#### `TimeInput`

#### `class TimeInput`

Saisie d’heure sous forme de zone de texte simple : `<input type='text' ...>`

Accepte les mêmes paramètres que [`TextInput`](#django.forms.TextInput), avec en plus un paramètre facultatif :

#### `format`

Le format dans lequel la valeur initiale du champ est affichée.

Si aucun paramètre `format` n’est indiqué, le format par défaut est le premier format trouvé dans [`TIME_INPUT_FORMATS`](/fr/1.9/ref/settings/#std-setting-TIME_INPUT_FORMATS) en respectant la [Régionalisation des formats](/fr/1.9/topics/i18n/formatting/).

Pour le traitement des microsecondes, référez-vous à [`DateTimeInput`](#django.forms.DateTimeInput).

#### `Textarea`

#### `class Textarea`

Zone de texte étendue : `<textarea>...</textarea>`

### Composants cases à cocher et listes à choix

#### `CheckboxInput`

#### `class CheckboxInput`

Case à cocher : `<input type='checkbox' ...>`

Accepte un paramètre facultatif :

#### `check_test`

Un objet exécutable acceptant la valeur de `CheckboxInput` et renvoyant `True` si la case à cocher doit apparaître cochée pour cette valeur.

#### `Select`

#### `class Select`

Composant de liste à choix : `<select><option ...>...</select>`

#### `choices`

Cet attribut est facultatif lorsque le champ de formulaire n’a pas d’attribut `choices`. Si l’attribut de champ est présent, il écrase tout ce que vous pourriez définir ici au moment où l’attribut est mis à jour au niveau du champ [`Field`](/fr/1.9/ref/forms/fields/#django.forms.Field).

#### `NullBooleanSelect`

#### `class NullBooleanSelect`

Composant de liste à choix avec les options « Inconnu », « Oui » et « Non »

#### `SelectMultiple`

#### `class SelectMultiple`

Semblable à [`Select`](#django.forms.Select), mais autorise les sélections multiples : `<select multiple='multiple'>...</select>`

#### `RadioSelect`

#### `class RadioSelect`

Semblable à [`Select`](#django.forms.Select), mais affiché sous forme de liste de boutons radio dans des balises `<li>`:

```html
<ul>
  <li><input type='radio' name='...'></li>
  ...
</ul>
```

Pour un contrôle plus fin du balisage produit, vous pouvez passer en boucle les boutons radio dans le gabarit. En prenant comme exemple un formulaire `myform` avec un champ `beatles` utilisant un composant `RadioSelect`:

```html+django
{% for radio in myform.beatles %}
<div class="myradio">
    {{ radio }}
</div>
{% endfor %}
```

Cela produirait le code HTML suivant :

```html
<div class="myradio">
    <label for="id_beatles_0"><input id="id_beatles_0" name="beatles" type="radio" value="john" /> John</label>
</div>
<div class="myradio">
    <label for="id_beatles_1"><input id="id_beatles_1" name="beatles" type="radio" value="paul" /> Paul</label>
</div>
<div class="myradio">
    <label for="id_beatles_2"><input id="id_beatles_2" name="beatles" type="radio" value="george" /> George</label>
</div>
<div class="myradio">
    <label for="id_beatles_3"><input id="id_beatles_3" name="beatles" type="radio" value="ringo" /> Ringo</label>
</div>
```

Les balises `<label>` y figurent également. Pour un contrôle encore plus fin, vous pouvez utiliser les attributs `tag`, `choice_label` et `id_for_label` de chaque bouton radio. Par exemple, ce gabarit…

```html+django
{% for radio in myform.beatles %}
    <label for="{{ radio.id_for_label }}">
        {{ radio.choice_label }}
        <span class="radio">{{ radio.tag }}</span>
    </label>
{% endfor %}
```

…produit le code HTML suivant :

```html
<label for="id_beatles_0">
    John
    <span class="radio"><input id="id_beatles_0" name="beatles" type="radio" value="john" /></span>
</label>

<label for="id_beatles_1">
    Paul
    <span class="radio"><input id="id_beatles_1" name="beatles" type="radio" value="paul" /></span>
</label>

<label for="id_beatles_2">
    George
    <span class="radio"><input id="id_beatles_2" name="beatles" type="radio" value="george" /></span>
</label>

<label for="id_beatles_3">
    Ringo
    <span class="radio"><input id="id_beatles_3" name="beatles" type="radio" value="ringo" /></span>
</label>
```

Si vous décidez de ne pas passer en boucle les boutons radio, par exemple si le gabarit contient simplement `{{ myform.beatles }}`, ils seront contenus dans un élément `<ul>` avec des balises `<li>`, comme ci-dessus.

The outer `<ul>` container receives the `id` attribute of the widget,
if defined, or [`BoundField.auto_id`](/fr/1.9/ref/forms/api/#django.forms.BoundField.auto_id) otherwise.

Lors de l’itération sur les boutons radio, les balises\`\`label\`\` and `input`  incluent les attributs `for` et `id`, respectivement. Chaque bouton radio inclut un attribut `id_for_label` produisant l’ID de l’élément.

#### `CheckboxSelectMultiple`

#### `class CheckboxSelectMultiple`

Semblable à [`SelectMultiple`](#django.forms.SelectMultiple), mais affiché sous forme de liste de cases à cocher :

```html
<ul>
  <li><input type='checkbox' name='...' ></li>
  ...
</ul>
```

The outer `<ul>` container receives the `id` attribute of the widget,
if defined, or [`BoundField.auto_id`](/fr/1.9/ref/forms/api/#django.forms.BoundField.auto_id) otherwise.

Comme pour [`RadioSelect`](#django.forms.RadioSelect), vous pouvez maintenant passer en boucle les cases à cocher individuelles composant les listes. Consultez la documentation de [`RadioSelect`](#django.forms.RadioSelect) pour plus de détails.

Lors de l’itération sur les cases à cocher, les balises\`\`label\`\` and `input`  incluent les attributs `for` et `id`, respectivement. Chaque case à cocher inclut un attribut `id_for_label` produisant l’ID de l’élément.

### Composants d’envoi de fichier

#### `FileInput`

#### `class FileInput`

Sélection de fichier à envoyer : `<input type='file' ...>`

#### `ClearableFileInput`

#### `class ClearableFileInput`

Sélection de fichier à envoyer : `<input type='file' ...>`, avec une case à cocher supplémentaire pour effacer la valeur du champ, si le champ n’est pas obligatoire et qu’il comporte une donnée initiale.

### Composants multiples

#### `MultipleHiddenInput`

#### `class MultipleHiddenInput`

Plusieurs composants `<input type='hidden' ...>`.

Un composant qui gère plusieurs composants masqués pour des champs qui possèdent une liste de valeurs.

#### `choices`

Cet attribut est facultatif lorsque le champ de formulaire n’a pas d’attribut `choices`. Si l’attribut de champ est présent, il écrase tout ce que vous pourriez définir ici au moment où l’attribut est mis à jour au niveau du champ [`Field`](/fr/1.9/ref/forms/fields/#django.forms.Field).

#### `SplitDateTimeWidget`

#### `class SplitDateTimeWidget`

Wrapper (using [`MultiWidget`](#django.forms.MultiWidget)) around two widgets: [`DateInput`](#django.forms.DateInput)
for the date, and [`TimeInput`](#django.forms.TimeInput) for the time. Must be used with
[`SplitDateTimeField`](/fr/1.9/ref/forms/fields/#django.forms.SplitDateTimeField) rather than [`DateTimeField`](/fr/1.9/ref/forms/fields/#django.forms.DateTimeField).

`SplitDateTimeWidget` contient deux attributs facultatifs :

#### `date_format`

Semblable à [`DateInput.format`](#django.forms.DateInput.format)

#### `time_format`

Semblable à [`TimeInput.format`](#django.forms.TimeInput.format)

#### `SplitHiddenDateTimeWidget`

#### `class SplitHiddenDateTimeWidget`

Semblable à [`SplitDateTimeWidget`](#django.forms.SplitDateTimeWidget), mais utilise [`HiddenInput`](#django.forms.HiddenInput) à la fois pour la date et l’heure.

#### `SelectDateWidget`

#### `class SelectDateWidget`

Composant parent de trois sous-composants [`Select`](#django.forms.Select) pour le mois, le jour et l’année.

Accepte plusieurs paramètres facultatifs :

#### `years`

Une liste (ou tuple) facultative d’années à présenter dans la liste à choix « year ». La valeur par défaut est une liste contenant l’année en cours et les 9 années suivantes.

#### `months`

Un dictionnaire facultatif de mois à utiliser dans la liste de sélection « months ».

Les clés du dictionnaire correspondent au numéro du mois (indice à partir de 1) et les valeurs sont les mois affichés :

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

> **New in Django 1.8**

Si le champ [`DateField`](/fr/1.9/ref/forms/fields/#django.forms.DateField) n’est pas obligatoire, [`SelectDateWidget`](#django.forms.SelectDateWidget) comportera un choix vide au sommet de la liste (qui s’affiche comme `---` par défaut). Vous pouvez modifier le texte de ce choix avec l’attribut `empty_label`. `empty_label` peut être une chaîne, une liste ou un tuple. Lorsqu’une chaîne est utilisée, toutes les listes de choix auront chacune un choix vide avec ce contenu. Si `empty_label` est une liste ou un tuple de 3 éléments textuels, les listes de choix possèdent chacune leur propre contenu. Les textes doivent apparaître dans cet ordre : `('texte_année', 'texte_mois', 'texte_jour')`.

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

> **Changed in Django 1.9**
>
> Ce composant se trouvait précédemment dans le module `django.forms.extras.widgets`. Il est maintenant défini dans `django.forms.widgets` et il peut être directement importé depuis `django.forms` comme les autres composants.
