Outils pour utilisateurs

Outils du site


dev:python:flask:flask_formulaires_wtforms

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
dev:python:flask:flask_formulaires_wtforms [2025/02/27 20:00] yoanndev:python:flask:flask_formulaires_wtforms [2026/04/12 10:26] (Version actuelle) yoann
Ligne 1: Ligne 1:
-{{tag>dev python web formulaire}}+{{tag>dev python flask web formulaire}}
  
-:TODO:+:TODO_DOCUPDATE:
  
-====== Python Gestion des formulaires via Flask-WTF ======+====== Flask Créer des formulaires via Flask-WTF ======
  
 [[https://wtforms.readthedocs.io/en/3.2.x/|WTForms]] est une bibliothèque Python permettant de gérer des formulaires web via des Classes et objets en POO. [[https://wtforms.readthedocs.io/en/3.2.x/|WTForms]] est une bibliothèque Python permettant de gérer des formulaires web via des Classes et objets en POO.
Ligne 9: Ligne 9:
 Ici on utilise le paquet Flask-WTF qui intègre la bibliothèque WTForms au micro framework Flask.  Ici on utilise le paquet Flask-WTF qui intègre la bibliothèque WTForms au micro framework Flask. 
  
 +===== Initialiser l'application Flask =====
  
-Initialisation du projet :+Création d'un dépôt git pour le projet et initialisation de l'application Flask :
  
 <code bash> <code bash>
Ligne 17: Ligne 18:
 git branch -m main git branch -m main
  
-# Création de l'environnement et installation des modules+# Création de l'environnement et installation des packages
 python3 -m venv venv python3 -m venv venv
 source venv/bin/activate source venv/bin/activate
-pip install Flask Flask-WTF+pip install Flask Flask-WTF email_validator
  
 # Création de l'application Flask # Création de l'application Flask
Ligne 64: Ligne 65:
  
 A ce stade la commande doit lancer le serveur web et afficher un message du type : A ce stade la commande doit lancer le serveur web et afficher un message du type :
 +
 <file> <file>
 * Serving Flask app 'helloforms' * Serving Flask app 'helloforms'
Ligne 80: Ligne 82:
  
  
 +Pour la mise en forme, on utilise le framework Spectre CSS
  
 +
 +===== Création du formulaire =====
 +
 +  * Pour créer un formulaire, on définit une classe héritant de **FlaskForm**.
 +  * Chaque attribut de la notre classe représentant un champ de formulaire sera un objet héritant de la classe de base ''wtforms.fields.Field'' ;
 +  * L'objet de type formulaire est instancié et traité par le contrôleur (la fonction associée à la route Flask) et transmis à la vue (le template).
 +
 +
 +<code python>
 +from flask_wtf import FlaskForm
 +from wtforms import EmailField, SubmitField
 +from wtforms.fields.simple import BooleanField
 +
 +class NewsLetterForm(FlaskForm):
 +
 +    email = EmailField(label='Email')
 +    news_letter = BooleanField(label="S'abonner à la news letter")
 +    submit_button = SubmitField(label='Valider')
 +</code>
 +
 +Comme illustré ci-dessus, le constructeur des objets héritant de la classe de base ''wtforms.fields.Field'' accepte notamment les paramètres :
 +  * ''label'' : le label associé au champ ;
 +  * ''default'' : valeur par défaut du champ, peut être un ''callable'' (un nom de fonction exécutable) ;
 +  * ''description'' : une description associée au champ, utilisée généralement par les help text ;
 +  * ''filters'' : tableau, séquence de ''callable'' exécutés pour traiter les données du champ ;
 +  * ''validators'' : tableau de validators appelés lors de l'exécution de ''validate''.
 +
 +
 +La liste exhaustive des paramètres est disponible dans la documentation [[https://wtforms.readthedocs.io/en/3.2.x/fields/#basic-fields]]
 +
 +
 +Quelques objets représentant les champs de base des formulaires :
 +
 +  * **StringField** : Champ type texte ;
 +  * **TextAreaField** :
 +  * **SelectField** : 
 +  * **BooleanField** : Champ de type checkbox ;
 +  * **PasswordField**  : Champ de saisie de mot de passe
 +  * **HiddenField** : Champ masqué ;
 +  * **SubmitField** : Bouton soumission du formulaire ;
 +
 +
 +Champs plus spécifiques :
 +  * **EmailField** ;
 +  * **TelField** ;
 +  * **URLField** ;
 +  * **TimeField** ;
 +  * **ColorField** ; 
 +  * **IntegerField** : Saisie d'un nombre entier;
 +  * **IntegerRangeField**
 +  * **FloatField** 
 +  * **DecimalRangeField** ;
 +  * **FileField**
 +
 +
 +
 +===== Les filtres =====
 +
 +Les filtres (filters) permettent de traiter, en amont de la validation, les valeurs saisies par l'utilisateur. On les utilise couramment pour :
 +
 +  * Retirer les espaces en début et fin de saisie ;
 +  * Passer la saisie en majuscule, en minuscule ;
 +  * Arrondir les valeurs décimales etc.
 +
 +
 +<code python>
 +from flask_wtf import FlaskForm
 +from wtforms import StringField
 +
 +class RegisterForm(FlaskForm):
 +
 +    lastname = StringField(label='Nom', default="DOE",
 +                           filters=[str.strip, str.upper],
 +                           description="Champ de saisie de votre nom")
 +
 +</code>
 +
 +Ci-dessus, on utilise les filtres pour retirer les espaces autour de la saisie et la passer en majuscules.
 +
 +===== Les validateurs =====
 +
 +Les **validators** permettent de contrôler la saisie de l'utilisateur. On les importe depuis ''wtforms.validators''.
 +
 +
 +<code python>
 +from flask_wtf import FlaskForm
 +from wtforms import StringField
 +from wtforms.validators import InputRequired, Email
 +
 +class RegisterForm(FlaskForm):
 +
 +    email = StringField(label='Email', validators=[InputRequired(),Email()])
 +</code>
 +
 +Ici on instancie deux validators pour contraindre la saisie de l'utilisateur :
 +  * Le champs ne doit pas être vide,
 +  * La saisie doit respecter le formalisme d'un email.
 +
 +Dans ce cas, peut également utiliser la classe ''EmailField''
 +
 +<code python>
 +from flask_wtf import FlaskForm
 +from wtforms import EmailField
 +
 +
 +class RegisterForm(FlaskForm):
 +
 +    email = EmailField(label='Email')
 +</code>
 +
 +Il existe de nombreux validators citons par exemple **InputRequired**, **Length**, **Email**, **URL**, **NumberRange**, **IPAddress**, **MacAddress**, **Regexp**, etc. Il est possible de définir ses propres validators.
 +
 +  * Ici la [[https://wtforms.readthedocs.io/en/3.2.x/validators/|documentation exhaustive des validators WTForms]]
 +
 +
 +
 +===== Rendu du formulaire dans le template =====
 +
 +Du côté du template, on peut s'appuyer sur des macros Jinja2 pour factoriser le code en charge de produire le HTML du formulaire :
 +
 +<code html _helpers.html>
 +{#
 +Produire le code HTML d'un champ de formulaire.
 +#}
 +
 +{% macro render_field_with_div(field) %}
 +<div>
 +    {{ field.label }} {{ field(**kwargs)|safe }}
 +        {% if field.errors %}
 +            <ul class=errors>
 +            {% for error in field.errors %}
 +                <li>{{ error }}</li>
 +            {% endfor %}
 +            </ul>
 +    {% endif %}
 +</div>
 +{% endmacro %}
 +</code>
 +
 +Une fois la macro définie, on peut l'utiliser dans les différents modèles produisant des formulaires.
 +
 +<code html>
 +<div>
 +    {% from "_helpers.html" import render_field_with_div %}
 +    <form method="POST" action="{{ url_for('frontend.parse_contact_form') }}">
 +        {{ form.csrf_token }}
 +        {{ render_field_with_div(form.first_name) }}
 +        {{ render_field_with_div(form.last_name) }}
 +        {{ render_field_with_div(form.email) }}
 +        {{ render_field_with_div(form.subject) }}
 +        {{ render_field_with_div(form.message) }}
 +        {{ render_field_with_div(form.submit_button) }}
 +    </form>
 +</div>
 +</code>
 +
 +===== Validation =====
 +
 +C'est la fonction contrôleur de la vue qui se charge de valider le formulaire retourné en méthode POST.
 +
 +<code python [highlight_lines_extra="7"] >
 +@frontend_bp.post('/contact')
 +def parse_contact_form():
 +    """
 +    Analyse le formulaire de contact renseigné par l'utilisateur.
 +    """
 +    from app.services.forms import ContactForm
 +    form = ContactForm()
 +    if form.validate_on_submit():
 +        # Les valeurs saisies sont correctes
 +        return redirect(url_for('frontend.supply_home'))
 +    else:
 +        # Reafficher le formulaire pour permettre à l'utilisateur de corriger
 +        flash('Vérifier les valeurs saisies')
 +        return render_template('contact.html', form=form)
 +</code>
 +
 +<note>
 +L'exemple montre bien qu'il n'est pas nécessaire de passer l'objet ''request.form'' à l'instanciation du formulaire ContactForm (héritant de FlaskForm) : il sera automatiquement chargé.
 +</note>
 +
 +La méthode ''validate_on_submit()'' vérifie que la méthode POST est utilisée et que le la saisie est valide.
 +
 +
 +===== Débogages =====
 +
 +==== Échec systématique de la validation ====
 +
 +Lors du traitement du formulaire dans la vue, celui-ci est systématiquement considéré comme invalide.
 +
 +
 +Lorsqu'un formulaire hérite de ''FlaskForm'', il contient systématiquement un **jeton CSRF** (processus de sécurité). Celui-ci doit être rendu dans le template. 
 + 
 +<code html>
 +<form method="POST" action="/">
 +    {{ form.csrf_token }}
 +    
 +    <!-- vos autres champs ici -->
 +     
 +    <input type="submit" value="Go">
 +</form>
 +</code>
  
 ===== Références ===== ===== Références =====
  
-  * [[https://flask-wtf.readthedocs.io/en/1.2.x/|Documentation Officielle Flask-WTF]] +  * [[https://flask-wtf.readthedocs.io/en/1.2.x/|Documentation Flask-WTF]] 
-  * [[https://wtforms.readthedocs.io/en/3.2.x/|Documentaion Officielle WTForms]]+  * [[https://flask.palletsprojects.com/en/stable/patterns/wtforms/| Documentation Flask : validation des formulaires WTF (palletsprojects.com) (en)]] 
 +  * [[https://wtforms.readthedocs.io/en/3.2.x/|Documentation Officielle WTForms]] 
 +  * [[https://spectre-org.github.io/spectre-docs/docs/get-started/|Documentation Framework CSS Spectre]]
   * https://zephyrnet.com/fr/manipulation-de-formulaires-en-flacon-avec-flacon-wtforms/   * https://zephyrnet.com/fr/manipulation-de-formulaires-en-flacon-avec-flacon-wtforms/
   * https://fr.python-3.com/?p=1882   * https://fr.python-3.com/?p=1882
-  * https://youtu.be/HvEkVffiNXQ +  * Vidéo [[https://youtu.be/HvEkVffiNXQ| Créer des formulaires avec Flask-WTF]] 
-  * +  * https://picturepan2.github.io/spectre/getting-started.html 
 +  * https://spectre-org.github.io/spectre-docs/docs/layout/ 
 +  * [[https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-iii-web-forms| Les formulaires dans Flask (miguelgrinberg.com)]] 
 + 
dev/python/flask/flask_formulaires_wtforms.1740686451.txt.gz · Dernière modification : 2025/02/27 20:00 de yoann