exercices : premier template, première route, premier passage de paramètres à un template

vidéo (niveau NSI) pour bien démarrer flask si on va trop vite et dont s’inspirent ces exercices : FLASK (Un prof de NSI)

lien sur son code source

exercice 1 : rôle des routes


  1. Dans le fichier app.py, modifiez la réponse de la route /hello
@app.route('/')
@app.route('/hello')
def hello_world():  # put application's code here
    return 'Hello World!<a href="hello">lien hello</a>  &nbsp; <a href="/heure"> heure </a>'
  1. Dans le fichier app.py, ajoutez une autre route /heure qui appelle un template index_demo.html
@app.route('/heure')
def heure():
    date_heure = datetime.datetime.now()
    h = date_heure.hour
    m = date_heure.minute
    s = date_heure.second
    return render_template('index_demo.html', h=h,min=m,sec=s )
  1. Dans le fichier app.py, ajoutez la bibliothèque datetime sous l’instruction from flask import Flask. Importez plusieurs fonctions dans la bibliothèque flask : request, render_template, redirect, flash si ce n’est pas fait.
from flask import Flask, request, render_template, redirect,flash
import datetime
  1. Dans le dossier templates, créez le template (fichier) index_demo.html


  1. Dans le dossier templates, complétez le fichier index_demo.html : utilisez le snippet html:5 , puis dans la balise <body> ajoutez le code ci-dessous :
    <p> heure = {{ h }} , minute = {{ m }}, seconde  = {{ sec }}</p>

    <br>
    <a href="/">home</a>

code branche 1

Il faut corriger le nom de la variable : remplacer m par min


exercice 2 : récupérer les paramètres dans un lien et les champs input dans un formulaire

vidéo (niveau NSI) pour bien démarrer Flask dont est inspiré cet exercice

nous allons utiliser un tableau de dictionnaires de données

liste_etudiants = [
    {'id':1,'nom':'tom', 'groupe':'A1'},
    {'id':2,'nom':'enzo', 'groupe':'A1'},
    {'id':3,'nom':'laurence', 'groupe':'A2'},
    {'id':4,'nom':'theo', 'groupe':'A2'},
    {'id':5,'nom':'mehdi', 'groupe':'B1'}
]
  1. Dans le fichier app.py, ajoutez ce tableau au début du fichier d’application flask après avoir importé les bibliothèques. .

  2. Dans le fichier app.py, créez une route /etudiant/show qui appelle la fonction show_etudiants

  3. À l’intérieur du dossier templates, créez un dossier etudiant ; dans le dossier templates/etudiant/ créez une vue (un fichier template) show_etudiant.html.

  4. Dans le fichier app.py, dans la fonction show_etudiants, passez en paramètre la liste liste_etudiants avec comme nom etudiants dans la fonction render_template.

  5. Dans le fichier templates/etudiant/show_etudiant.html, affichez la liste des étudiants : ajoutez le code ci-dessous dans la balise <body>.

<h1>listes des étudiants</h1>

{{ etudiants }}
  1. Dans le fichier templates/index_demo.html, ajoutez un lien vers la page des étudiants show_etudiant.html
    <br>
    <a href="/etudiant/show">etudiants</a>

code branche 2

  1. Dans le fichier templates/etudiant/show_etudiant.html, affichez la liste des étudiants dans un tableau ; il faut utiliser une boucle :
<table>
    {% for etudiant in etudiants %}
         <tr>
                <td>{{ etudiant }}</td>
           </tr>
        {% endfor %}
</table>
  1. Dans le fichier templates/etudiant/show_etudiant.html, remplacez la ligne qui affiche chaque étudiant par le code ci-dessous :
<table class="table">
    <thead class="thead-dark">
    <tr>
        <th>id</th><th>nom</th><th>groupe</th>
    </tr>
    </thead>
    {% for etudiant in etudiants %}
    <tr>
        {# commentaires : autre notation possible, on affiche un element du dictionnaire               
                <td>{{ etudiant['id'] }}</td><td>{{ etudiant['nom'] }}</td><td>{{ etudiant['groupe'] }}</td>
        #}
        <td>{{ etudiant.id }}</td><td>{{ etudiant.nom }}</td><td>{{ etudiant.groupe }}</td>
    </tr>
    {% endfor %}
</table>
  1. Testez l’affichage du fichier templates/etudiant/show_etudiant.html avec un tableau de dictionnaires d’étudiants vide dans le fichier app.py

  2. Dans le fichier templates/etudiant/show_etudiant.html, affichez la liste des étudiants si le tableau n’est pas vide en intégrant le code ci-dessous dans le template show_etudiant.html

    {% if etudiants | length >= 1 %}
       ...
    {% else %}
           <h2> la liste des étudiants est vide</h2> 
    {% endif %}

autre exemple : cours NSI

Sur les outils JetBrains
Remarque : Ctrl+Alt+i => indentation
Ctrl+r => rechercher/remplacer
Dans le contrôleur Ctrl+clic sur le nom d’un template dans le contrôleur (app)

(Etape au bout de la première séance minimum)

code branche 3

Utilisation de liens

  1. Dans le fichier templates/etudiant/show_etudiant.html : Ajoutez, dans chaque ligne, 2 liens : un lien pour modifier et un lien pour supprimer la ligne. Ajoutez dans chaque lien une route avec au bout de chaque route un paramètre : l’identifiant de l’étudiant ?id= suivi de la valeur de l’identifiant de l’étudiant : {{ etudiant.id }}.

  2. Ajoutez un lien pour ajouter un étudiant avant l’affichage du tableau

Code pour l’étape 16 et 17 :

<a href="/etudiant/add" >ajouter un étudiant</a>


....


<td>
    <a href="/etudiant/edit?id={{ etudiant.id }}"   class="btn btn-success">editer</a>&nbsp;
    <a href="/etudiant/delete?id={{ etudiant.id }}"   class="btn btn-success">supprimer</a>
</td>

Passage de paramètres

  1. Dans le fichier app.py (application flask) , créez 3 routes /etudiant/add , /etudiant/delete et /etudiant/edit associées à 3 fonctions add_etudiant , delete_etudiant et edit_etudiant

Code pour l’étape 18 :

@app.route('/etudiant/add')
def add_etudiant():
    print('''affichage du formulaire pour saisir un étudiant''')
    return render_template('etudiant/add_etudiant.html')

@app.route('/etudiant/delete')
def delete_etudiant():
    print('''suppression d'un étudiant''')

@app.route('/etudiant/edit')
def edit_etudiant():
    print('''affichage du formulaire pour modifier un étudiant''')
    return render_template('etudiant/edit_etudiant.html')

Utilisation de paramètres issus de liens

voici le code HTML généré par ChatGPT (2025) pour saisir les informations d’un étudiant :


(code généré en saisissant le prompt : donner le code HTML d’un formulaire en utilisant le framework Bootstrap 5 pour saisir les informations du tableau Python : )

<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Formulaire Étudiant</title>
  <!-- Bootstrap 5 -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">

<div class="container py-4">
  <h2 class="mb-4">Formulaire étudiant</h2>

  <form>
    <!-- Champ caché ID -->
    <input type="hidden" name="id" value="1">

    <!-- Nom -->
    <div class="mb-3">
      <label for="nom" class="form-label">Nom</label>
      <input type="text" class="form-control" id="nom" name="nom" value="">
    </div>

    <!-- Groupe -->
    <div class="mb-3">
      <label for="groupe" class="form-label">Groupe</label>
      <select class="form-select" id="groupe" name="groupe">
        <option value="A1" selected>A1</option>
        <option value="A2">A2</option>
        <option value="B1">B1</option>
      </select>
    </div>

    <!-- Boutons -->
    <button type="submit" class="btn btn-primary">Enregistrer</button>
    <button type="reset" class="btn btn-secondary">Réinitialiser</button>
  </form>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
  1. créez 2 templates etudiant/add_etudiant.html et etudiant/edit_etudiant.html et copiez/adaptez le contenu du formulaire ci-dessus :

code branche 4

  1. Dans le fichier app.py, dans les 2 fonctions delete_etudiant et edit_etudiant, affichez à l’aide de l’instruction print dans le terminal le paramètre reçu de nom id. Utilisez la fonction print(request.args).

Pour delete_etudiant , une erreur est générée car il n’y a pas de réponse retournée au navigateur (pas de return)

redirection

  1. À la fin de la fonction delete_etudiant faire une redirection sur la route show_etudiants avec l’instruction :


return redirect('/etudiant/show')

  1. Dans le fichier app.py, ajoutez le code ci-dessous dans la fonction delete_etudiant
    id=request.args.get('id')
    message='paramètre dans l URL : '+id
    print(message)
  1. Dans le fichier app.py, dans la fonction edit_etudiant, ajoutez le code ci-dessous :
    id=request.args.get('id')
    if id != None and id.isnumeric():
        indice = int(id)
        etudiant=liste_etudiants[indice-1]
    else:
        etudiant=[]
    print("etudiant"+etudiant)
  1. Dans le fichier app.py, dans la fonction edit_etudiant, passez en paramètre l’étudiant sélectionné au template edit_etudiant.html. Affichez dans chaque champ input de ce template la valeur de l’information concernant l’étudiant (id, nom, groupe). ATTENTION, pour la liste déroulante, c’est plus difficile et ce sera abordé plus tard.


Dans app.py

    return render_template('etudiant/edit_etudiant.html', etudiant=etudiant)

Dans edit_etudiant.html

...
    <input type="hidden" name="id" value="{{ etudiant.id }}">
...
   <input type="text" class="form-control" id="nom" name="nom" value="{{ etudiant.nom }}">
...

code branche 5

Utilisation des paramètres issus d’un formulaire

  1. Dans le fichier app.py, créez 2 routes /etudiant/add et /etudiant/edit dans le fichier de l’application flask associées à 2 fonctions valid_add_etudiant et valid_edit_etudiant
@app.route('/etudiant/add', methods=['POST'])
def valid_add_etudiant():
    print('''ajout de l'étudiant dans le tableau''')
    return redirect('/etudiant/show')

@app.route('/etudiant/edit', methods=['POST'])
def valid_edit_etudiant():
    print('''modification de l'étudiant dans le tableau''')
    return redirect('/etudiant/show')
  1. Dans les 2 templates etudiant/add_etudiant.html et etudiant/edit_etudiant.html, ajoutez dans les balises <form> des 2 formulaires des templates les attributs action="/etudiant/add" method="post" ou les attributs action="/etudiant/edit" method="post"

  2. Dans le fichier app.py, indiquez pour les routes des 2 fonctions add_etudiant et edit_etudiant la méthode pour la route : il faut ajouter dans l’annotation , methods=['GET']

  3. Affichez dans le terminal dans les 2 fonctions valid_add_etudiant et valid_edit_etudiant les paramètres reçus de chaque formulaire print(request.form)

  4. Dans le fichier app.py, dans la fonction valid_add_etudiant , créez un message avec les informations pour ajouter un étudiant

nom = request.form.get('nom')
groupe = request.form.get('groupe')
message = 'nom :'+nom+' - groupe :'+groupe    
print(message)
  1. Dans le fichier app.py, dans la fonction valid_edit_etudiant ,créez un message avec les informations pour modifier un étudiant
id = request.form.get('id')
nom = request.form.get('nom')
groupe = request.form.get('groupe')
message = 'nom :'+nom+' - groupe :'+groupe+' pour l etudiant d identifiant :'+id   
print(message)

Remarque : Dans le formulaire pour modifier les données d’un étudiant, il faut un champ caché avec l’identifiant de l’étudiant. Ce champ INPUT est obligatoire.

<input type="hidden" name="id" value="{{ etudiant.id }}" >


Fichiers “static”


  1. Supprimez la route /hello et la fonction hello_world ; associez la route / à la fonction show_etudiants
  2. Supprimez la route /heure et la fonction heure

Il n’est pas possible dans le dossier templates d’utiliser des fichiers CSS des images ….

  1. Placez le contenu du fichier ressources suivant dans le fichier static

code branche 6


Les fichiers STATIC sont tous des fichiers dont le contenu ne change jamais : les fichiers CSS (vos styles, bootstrap), les images, les fichiers JavaScript


Ce dossier s’appelle aussi public dans d’autres frameworks (Symfony Laravel …)


Dans Flask pour utiliser le contenu de ces fichiers dans les templates il faut utiliser la fonction : {{ url_for('static', filename='dossier_dans_static/nom_du_fichier') }}


Il est possible dans un template d’utiliser le contenu de dossier static grâce à la fonction url_for, exemple :

<link rel="icon"  href="{{ url_for('static', filename='iconeweb.ico') }}" />

<link rel="stylesheet" href="{{ url_for('static', filename='mes_styles.css') }}" >
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/css/bootstrap.css') }}" >


....
<img src="{{ url_for('static', filename='image_iut.jpeg') }}" alt="image iut"  />


....


<script src="{{ url_for('static', filename='bootstrap/js/bootstrap.js') }}"></script>

Un gabarit (template) est un fichier dont le contenu va être modifié par l’application. L’application va passer des paramètres (données) à la vue : la vue est renvoyée au client

principe du MVC

Héritage et liste déroulante

  1. héritage

Créez 2 fichiers dans le dossier templates, un fichier layout.html et un fichier **_nav.html** .


Contenu (code) du fichier layout.html :

<!doctype html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    {% block title %}
        <title>layout</title>
    {% endblock %}
    <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" >
    {% block stylesheets %}
        <link rel="stylesheet" href="{{ url_for('static', filename='mes_styles.css') }}" >
        <link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/css/bootstrap.css') }}" >
    {% endblock %}
</head>
<body>
{% include('_nav.html') %}

{% block body %}
    <h2 style="color:blue">layout.html</h2>  
{% endblock %}
{% block javascripts %}
    <script src="{{ url_for('static', filename='bootstrap/js/bootstrap.js') }}"></script>
{% endblock %}
</body>
</html>

Contenu (code) du fichier _nav.html :

<nav class="menu">
    <a href="/etudiant/show"> etudiants </a>  -
    <a href="/groupe/show"> groupes </a>  -
</nav>
<hr>
{% extends 'layout.html' %}

{% block title %}
    <title>gestion des étudiants</title>
{% endblock %}

{% block body %}

{% endblock %}



Dans le fichier layout.html, ajoutez la balise <div class="container"> sous l’instruction {% include('_nav.html') %} et fermez cette balise après la fin du bloc body

  1. Messages flash

Dans le fichier layout.html, ajoutez le code ci-dessous juste avant le block body

{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
    {% for categorie, message in messages %}
    <div role="alert" class="alert {{ categorie }}">
           Information : <strong>{{ message }}</strong>
    </div>
    {% endfor %}
{% endif %}
{% endwith %}

Dans le fichier app.py, ajoutez le code ci-dessous, juste après un print(message)

flash(message, 'alert-warning')
flash(message, 'alert-success')
  1. Liste déroulante
liste_etudiants = [
    {'id':'1','nom':'tom', 'groupe_id':'1'},
    {'id':'2','nom':'enzo', 'groupe_id':'1'},
    {'id':'3','nom':'laurence', 'groupe_id':'2'},
    {'id':'4','nom':'theo', 'groupe_id':'2'},
    {'id':'5','nom':'mehdi', 'groupe_id':'3'}
]

liste_groupes = [
    {'id': '1', 'libelle': 'A1'},
    {'id': '2', 'libelle': 'A2'},
    {'id': '3', 'libelle': 'B1'},
    {'id': '4', 'libelle': 'B2'}
]
<select name="id_groupe" required>
    <option value="">Sélectionner un groupe</option>
    {% for groupe in groupes %}
         <option value="{{ groupe.id }}"> {{ groupe.libelle }} </option>
    {% endfor %}
</select>
<select name="id_groupe" required>
    {% for groupe in groupes %}
    <option value="{{ groupe.id }}"
            {% if etudiant.groupe_id is defined and groupe.id == etudiant.groupe_id %}selected{% endif %}
    > {{ groupe.libelle }} </option>
    {% endfor %}
</select>
    return render_template('etudiant/add_etudiant.html', groupes=liste_groupes)
    return render_template('etudiant/edit_etudiant.html', etudiant=etudiant , groupes=liste_groupes)
 <td>{{ etudiant.id }}</td><td>{{ etudiant.nom }}</td><td>{{ etudiant.groupe_id }}</td>


Dans le fichier app.py, modifiez la récupération des données dans les fonctions appelées lors de la validation des formulaires ainsi que les messages flash avec le code ci-dessous dans les fonctions valid_add_etudiant et valid_edit_etudiant :

nom = request.form.get('nom')
id_groupe = request.form.get('id_groupe')
message = 'Ajout d un etudiant de nom :'+nom+' - id_groupe :' + id_groupe    
print(message)
id = request.form.get('id')
nom = request.form.get('nom')
id_groupe = request.form.get('id_groupe')
message = 'Modification du nom :'+nom+' - id_groupe :' + id_groupe + ' pour l etudiant d identifiant :' + id   
print(message)

Dans le fichier app.py, modifiez le message flash avec le code ci-dessous dans la fonction delete_etudiant :

id=request.args.get('id')
message='Suppression de  l etudiant d identifiant : : '+id
print(message)

Annexe

En cas de problème avec pycharm (blocage) : supprimez le dossier .cache/jetbrains/pycharm


problème version python