Le form, il s'assure que l'utilisateur n'a pas encodé de conneries et
que l'ensemble reste cohérent. Il (le form) n'a pas à savoir que tu as
implémenté des closure tables dans un graph dirigé acyclique.
\end{quote}
Quand on parle de \texttt{forms}, on ne parle pas uniquement de formulaires Web.
On pourrait considérer qu'il s'agit de leur objectif principal, mais on peut également voir un peu plus loin: on peut en fait voir les \texttt{forms} comme le point d'entrée pour chaque donnée arrivant dans notre application: il s'agit en quelque sorte d'un ensemble de règles complémentaires à celles déjà présentes au niveau du modèle.
L'exemple le plus simple est un fichier \texttt{.csv}: la lecture de ce fichier pourrait se faire de manière très simple, en récupérant les valeurs de chaque colonne et en l'introduisant dans une instance du modèle.
Mauvaise idée. On peut proposer trois versions d'un même code, de la version simple (lecture du fichier csv et jonglage avec les indices de colonnes), puis une version plus sophistiquée (et plus lisible, à base
de \href{https://docs.python.org/3/library/csv.html\#csv.DictReader}{DictReader}), et la version + à base de form.
Les données fournies par un utilisateur \textbf{doivent}\textbf{toujours} être validées avant introduction dans la base de données.
Notre base de données étant accessible ici par l'ORM, la solution consiste à introduire une couche supplémentaire de validation.
Le flux à suivre est le suivant:
\begin{enumerate}
\item
Création d'une instance grâce à un dictionnaire
\item
Validation des données et des informations reçues
\item
Traitement, si la validation a réussi.
\end{enumerate}
Ils jouent également deux rôles importants:
\begin{enumerate}
\item
Valider des données, en plus de celles déjà définies au niveau du modèle
\item
Contrôler le rendu à appliquer aux champs.
\end{enumerate}
Ils agissent come une glue entre l'utilisateur et la modélisation de vos structures de données.
Le formulaire permet également de contrôler le rendu qui sera appliqué lors de la génération de la page.
Si les champs dépendent du modèle sur lequel se base le formulaire, ces widgets doivent être initialisés dans
l'attribut \texttt{Meta}.
Sinon, ils peuvent l'être directement au niveau du champ.
\subsection{Squelette par défaut}
On a d'un côté le \{\{ form.as\_p \}\} ou \{\{ form.as\_table \}\}, mais il y a beaucoup mieux que ça ;-) Voir les templates de Vitor et en passant par \texttt{widget-tweaks}.
Dès qu'on souhaite peaufiner un peu l'affichage, contrôler parfaitement ce que l'utilisateur doit remplir,
modifier les types de contrôleurs, les placer au pixel près, ...
Tout ça demande énormément de temps.
Et c'est là qu'intervient \href{http://django-crispy-forms.readthedocs.io/en/latest/}{Django-Crispy-Forms}.
Cette librairie intègre plusieurs frameworks CSS (Bootstrap, Foundation et uni-form) et permet de contrôler entièrement le \textbf{layout} et la présentation.
Toute donnée entrée par l'utilisateur, quelle qu'elle soit, \textbf{doit} passer par une instance de \texttt{form}: qu'il s'agisse d'un formulaire HTML, d'un fichier CSV, d'un parser XML, ...
Dès que des informations "de l'extérieur" font mine d'arriver dans le périmètre de votre application, il convient d'appliquer immédiatement des principes de sécurité reconnus.