Composant Django Form
Les composants de formulaire Django sont utilisés pour initialiser des pages, générer des balises HTML, et aussi valider les données soumises par les utilisateurs (en affichant des messages d'erreur).
Ordre d'affichage des messages d'erreur :
- Affichez d'abord les messages d'erreur provenant des attributs de champ, puis affichez les messages d'erreur provenant des hooks locaux.
- Si les messages d'erreur provenant des attributs de champ sont affichés, les messages d'erreur provenant des hooks locaux ne seront pas affichés.
- S'il y a des hooks globaux, les hooks globaux ne lanceront la validation qu'après que toutes les données ont été validées, et les messages d'erreur des hooks globaux seront obligatoirement affichés.
Pour utiliser les composants Form, vous devez d'abord importer forms :
from django import forms

Ensuite, nous créons un fichier My_forms.py dans le répertoire app01 :
app01/My_forms.py
from django import forms
from django.core.exceptions import ValidationError
from app01 import models
class EmpForm(forms.Form):
name = forms.CharField(min_length=4, label="Nom", error_messages={"min_length": "Vous êtes trop court.", "required": "Ce champ ne peut pas être vide !"})
age = forms.IntegerField(label="Âge")
salary = forms.DecimalField(label="Salaire")
from django.core.exceptions import ValidationError
from app01 import models
class EmpForm(forms.Form):
name = forms.CharField(min_length=4, label="Nom", error_messages={"min_length": "Vous êtes trop court.", "required": "Ce champ ne peut pas être vide !"})
age = forms.IntegerField(label="Âge")
salary = forms.DecimalField(label="Salaire")
Attributs du champ :
- label: Le texte affiché devant la zone de saisie.
- error_message: Personnalisez les messages d'erreur affichés. La valeur de l'attribut est un dictionnaire, où `required` est la clé pour définir le message d'erreur affiché lorsque le champ ne peut pas être vide.
app01/views.py
from django.shortcuts import render, HttpResponse
from app01.My_Forms import EmpForm
from app01 import models
from django.core.exceptions import ValidationError
# Créez vos vues ici.
def add_emp(request):
if request.method == "GET":
form = EmpForm()
return render(request, "add_emp.html", {"form": form})
else:
form = EmpForm(request.POST)
if form.is_valid(): # Effectuer la validation des données
# Validation réussie
data = form.cleaned_data # Les valeurs qui passent la validation sont placées dans cleaned_data.
data.pop('r_salary')
print(data)
models.Emp.objects.create(**data)
return HttpResponse(
'ok'
)
# return render(request, "add_emp.html", {"form": form})
else:
print(form.errors) # Afficher les messages d'erreur
clean_errors = form.errors.get("__all__")
print(222, clean_errors)
return render(request, "add_emp.html", {"form": form, "clean_errors": clean_errors})
from app01.My_Forms import EmpForm
from app01 import models
from django.core.exceptions import ValidationError
# Créez vos vues ici.
def add_emp(request):
if request.method == "GET":
form = EmpForm()
return render(request, "add_emp.html", {"form": form})
else:
form = EmpForm(request.POST)
if form.is_valid(): # Effectuer la validation des données
# Validation réussie
data = form.cleaned_data # Les valeurs qui passent la validation sont placées dans cleaned_data.
data.pop('r_salary')
print(data)
models.Emp.objects.create(**data)
return HttpResponse(
'ok'
)
# return render(request, "add_emp.html", {"form": form})
else:
print(form.errors) # Afficher les messages d'erreur
clean_errors = form.errors.get("__all__")
print(222, clean_errors)
return render(request, "add_emp.html", {"form": form, "clean_errors": clean_errors})
Ajoutez les règles suivantes au fichier app01/urls.py :
path('add_emp/', views.add_emp)
Modèle HTML :
app01/add_emp.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h3>Ajouter un employé</h3>{#1. Écrire manuellement des pages HTML#}<form action="" method="post">
<p>Nom :<input type="text" name="name"></p>
<p>Âge :<input type="text" name="age"></p>
<p>Salaire :<input type="text" name="salary"></p>
<input type="submit">
</form>{#2. Implémenté via la méthode as_p de l'objet formulaire#}
{#<form action="" method="post" novalidate>#}
{# {% csrf_token %}#}
{# {{ form.as_p }}#}
{# <input type="submit">#}
{#</form>#}
{#3. Récupérer manuellement les champs de l'objet formulaire#}
{#<form action="" method="post" novalidate>#}
{# {% csrf_token %}#}
{# <div>#}
{# <label for="id_{{ form.name.name }}">Nom</label>#}
{# {{ form.name }} <span>{{ form.name.errors.0 }}</span>#}
{# </div>#}
{# <div>#}
{# <label for="id_{{ form.age.name }}">Âge</label>#}
{# {{ form.age }} <span>{{ form.age.errors.0 }}</span>#}
{# </div>#}
{# <div>#}
{# <label for="id_salary">Salaire</label>#}
{# {{ form.salary }} <span>{{ form.salary.errors.0 }}</span>#}
{# </div>#}
{# <input type="submit">#}
{#</form>#}
{#4. Utiliser une boucle for pour afficher tous les champs#}
{#<form action="" method="post" novalidate>#}
{# {% csrf_token %}#}
{# {% for field in form %}#}
{# <div>#}
{# <label for="id_{{ field.name }}">{{ field.label }}</label>#}
{# {{ field }} <span>{{ field.errors.0 }}</span>#}
{# </div>#}
{# {% endfor %}#}
{# <input type="submit">#}
{#</form>#}
</body>
</html>
Le résultat de l'exécution est présenté dans la figure ci-dessous :

Hooks locaux et hooks globaux
Définir la classe Form :
app01/My_forms.py
from django import forms
from django.core.exceptions import ValidationError
from app01 import models
class EmpForm(forms.Form):
name = forms.CharField(min_length=5, label="Nom", error_messages={"required": "Ce champ ne peut pas être vide !",
"min_length": "Le nom d'utilisateur est trop court."})
age = forms.IntegerField(label="Âge")
salary = forms.DecimalField(max_digits=5, decimal_places=2, label="Salaire")
r_salary = forms.DecimalField(max_digits=5, decimal_places=2, label="Veuillez saisir à nouveau le salaire.")
def clean_name(self): # Hook local
val = self.cleaned_data.get("name")
if val.isdigit():
raise ValidationError("Le nom d'utilisateur ne peut pas être uniquement composé de chiffres.")
elif models.Emp.objects.filter(name=val):
raise ValidationError("Le nom d'utilisateur existe déjà !")
else:
return val
def clean(self): # Hook global pour confirmer si les deux salaires saisis sont cohérents.
val = self.cleaned_data.get("salary")
r_val = self.cleaned_data.get("r_salary")
if val == r_val:
return self.cleaned_data
else:
raise ValidationError("Veuillez confirmer si le salaire est cohérent.")
from django.core.exceptions import ValidationError
from app01 import models
class EmpForm(forms.Form):
name = forms.CharField(min_length=5, label="Nom", error_messages={"required": "Ce champ ne peut pas être vide !",
"min_length": "Le nom d'utilisateur est trop court."})
age = forms.IntegerField(label="Âge")
salary = forms.DecimalField(max_digits=5, decimal_places=2, label="Salaire")
r_salary = forms.DecimalField(max_digits=5, decimal_places=2, label="Veuillez saisir à nouveau le salaire.")
def clean_name(self): # Hook local
val = self.cleaned_data.get("name")
if val.isdigit():
raise ValidationError("Le nom d'utilisateur ne peut pas être uniquement composé de chiffres.")
elif models.Emp.objects.filter(name=val):
raise ValidationError("Le nom d'utilisateur existe déjà !")
else:
return val
def clean(self): # Hook global pour confirmer si les deux salaires saisis sont cohérents.
val = self.cleaned_data.get("salary")
r_val = self.cleaned_data.get("r_salary")
if val == r_val:
return self.cleaned_data
else:
raise ValidationError("Veuillez confirmer si le salaire est cohérent.")
views.py code du fichier :
app01/views.py
def add_emp(request):
if request.method == "GET":
form = EmpForm() # Initialiser l'objet formulaire
return render(request, "add_emp.html", {"form":form})
else:
form = EmpForm(request.POST) # Passer les données à l'objet formulaire
if form.is_valid(): # Effectuer la validation
data = form.cleaned_data
data.pop("r_salary")
models.Emp.objects.create(**data)
return redirect("/index/")
else: # Échec de la validation
clear_errors = form.errors.get("__all__") # Obtenir les informations d'erreur du hook global
return render(request, "add_emp.html", {"form": form, "clear_errors": clear_errors})
if request.method == "GET":
form = EmpForm() # Initialiser l'objet formulaire
return render(request, "add_emp.html", {"form":form})
else:
form = EmpForm(request.POST) # Passer les données à l'objet formulaire
if form.is_valid(): # Effectuer la validation
data = form.cleaned_data
data.pop("r_salary")
models.Emp.objects.create(**data)
return redirect("/index/")
else: # Échec de la validation
clear_errors = form.errors.get("__all__") # Obtenir les informations d'erreur du hook global
return render(request, "add_emp.html", {"form": form, "clear_errors": clear_errors})
Le code du fichier de modèle est le suivant :
app01/add_emp.html
<form action="" method="post" novalidate>
{% csrf_token %}
<div>
<label for="id_{{ form.name.name }}">Nom</label>
{{ form.name }} <span>{{ form.name.errors.0 }}</span>
</div>
<div>
<label for="id_{{ form.age.name }}">Âge</label>
{{ form.age }} <span>{{ form.age.errors.0 }}</span>
</div>
<div>
<label for="id_salary">Salaire</label>
{{ form.salary }} <span>{{ form.salary.errors.0 }}{{ clear_errors.0 }}</span>
</div>
<div>
<label for="id_r_salary">Veuillez saisir à nouveau le salaire.</label>
{{ form.r_salary }} <span>{{ form.r_salary.errors.0 }}{{ clear_errors.0 }}</span>
</div>
<input type="submit">
</forme>
Le résultat de l'exécution est présenté dans la figure ci-dessous :

