logo oujood
🔍

Les formulaires dans Django

Django dispose d'un système de formulaires intégré qui gère la génération du HTML, la validation des données et la protection CSRF. Ce chapitre couvre les deux approches : la classe Form pour les formulaires libres, et ModelForm pour les formulaires liés à un modèle.

OUJOOD.COM

Pourquoi utiliser le système de formulaires Django

Écrire des formulaires HTML à la main fonctionne, mais Django propose une alternative plus robuste. La classe Form génère le HTML, valide les données reçues, affiche les erreurs et protège contre les soumissions malformées — le tout dans un workflow cohérent qui évite de dupliquer la logique de validation entre le frontend et le backend.

Créer un formulaire avec la classe Form

Les formulaires Django se définissent dans un fichier forms.py à la racine de l'application. Chaque champ du formulaire est un attribut de classe qui correspond à un type de donnée.

  📋 Copier le code

# membres/forms.py
from django import forms

class MembreForm(forms.Form):
    prenom = forms.CharField(max_length=255, label='Prénom')
    nom    = forms.CharField(max_length=255, label='Nom')
    mail   = forms.EmailField(label='Email')
    age    = forms.IntegerField(min_value=0, max_value=120, required=False)

Les types de champs les plus courants :

CharField — texte court. Paramètres utiles : max_length, min_length.

EmailField — valide automatiquement le format email.

IntegerField — entier avec min_value et max_value optionnels.

BooleanField — case à cocher.

ChoiceField — liste déroulante avec un tuple de choix.

DateField — date avec format configurable.

FileField / ImageField — upload de fichiers.

Traiter le formulaire dans une vue

Une vue qui gère un formulaire doit traiter deux cas : l'affichage initial (requête GET) et la soumission (requête POST).

  📋 Copier le code

from django.shortcuts import render, redirect
from .forms import MembreForm
from .models import Membres

def ajouter_membre(request):
    if request.method == 'POST':
        # Formulaire soumis — on le remplit avec les données POST
        form = MembreForm(request.POST)
        if form.is_valid():
            # Données validées et nettoyées disponibles dans cleaned_data
            Membres.objects.create(
                prenom=form.cleaned_data['prenom'],
                nom=form.cleaned_data['nom'],
                mail=form.cleaned_data['mail'],
            )
            return redirect('index')
    else:
        # Requête GET — formulaire vide
        form = MembreForm()

    return render(request, 'ajout.html', {'form': form})

is_valid() déclenche la validation de tous les champs. Si les données sont correctes, elles sont disponibles dans form.cleaned_data — un dictionnaire avec les valeurs converties dans le bon type Python. Si la validation échoue, form.errors contient les messages d'erreur par champ.

Afficher le formulaire dans le template

Django peut générer le HTML du formulaire automatiquement depuis l'objet form passé par la vue :

  📋 Copier le code

<!DOCTYPE html>
<html>
<body>
<h1>Ajouter un membre</h1>

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}          <!-- Chaque champ dans un <p> -->
    <button type="submit">Enregistrer</button>
</form>

</body>
</html>

Trois méthodes de rendu automatique :

{{ form.as_p }} — enveloppe chaque champ dans un <p>.

{{ form.as_ul }} — génère une liste <ul>.

{{ form.as_table }} — génère un tableau HTML.

Rendu champ par champ pour plus de contrôle

Pour contrôler précisément le HTML généré, affichez chaque champ individuellement :

  📋 Copier le code

<form method="post">
    {% csrf_token %}

    <div>
        {{ form.prenom.label_tag }}   <!-- <label for="id_prenom">Prénom :</label> -->
        {{ form.prenom }}             <!-- <input type="text" name="prenom" ...> -->
        {{ form.prenom.errors }}      <!-- Messages d'erreur éventuels -->
    </div>

    <div>
        {{ form.mail.label_tag }}
        {{ form.mail }}
        {{ form.mail.errors }}
    </div>

    <button type="submit">Enregistrer</button>
</form>

ModelForm — formulaire lié à un modèle

ModelForm génère automatiquement les champs du formulaire à partir d'un modèle Django. C'est la solution la plus rapide quand le formulaire correspond directement à une table de la base de données.

  📋 Copier le code

from django import forms
from .models import Membres

class MembreModelForm(forms.ModelForm):
    class Meta:
        model  = Membres
        fields = ['prenom', 'nom', 'mail']  # Champs à inclure
        # Ou exclure certains champs :
        # exclude = ['date_creation']
        labels = {
            'prenom': 'Prénom',
            'nom':    'Nom de famille',
            'mail':   'Adresse email',
        }

La vue devient plus concise grâce à la méthode save() qui crée ou met à jour l'enregistrement directement :

  📋 Copier le code

from .forms import MembreModelForm

def ajouter_membre(request):
    if request.method == 'POST':
        form = MembreModelForm(request.POST)
        if form.is_valid():
            form.save()  # Crée directement l'enregistrement en base
            return redirect('index')
    else:
        form = MembreModelForm()
    return render(request, 'ajout.html', {'form': form})

def modifier_membre(request, id):
    membre = get_object_or_404(Membres, id=id)
    if request.method == 'POST':
        form = MembreModelForm(request.POST, instance=membre)
        if form.is_valid():
            form.save()  # Met à jour l'enregistrement existant
            return redirect('index')
    else:
        # Pré-remplit le formulaire avec les données du membre
        form = MembreModelForm(instance=membre)
    return render(request, 'modifier.html', {'form': form})

Passer instance=membre au formulaire le pré-remplit avec les données existantes et fait en sorte que save() mette à jour cet enregistrement plutôt d'en créer un nouveau.

Par carabde | Mis à jour le 05 mai 2025