vidéo (niveau NSI) pour bien démarrer flask si on va trop vite et dont s’inspire ces exercices : FLASK (Un prof de NSI)
@app.route('/')
@app.route('/hello')
def hello_world(): # put application's code here
return 'Hello World!<a href="hello">lien hello</a> <a href="/heure"> heure </a>'
@app.route('/heure')
def heure():
= datetime.datetime.now()
date_heure = date_heure.hour
h = date_heure.minute
m = date_heure.second
s return render_template('index_demo.html', h=h,min=m,sec=s )
from flask import Flask
. Importer plusieurs fonctions dans
la bibliothèque flask
.from flask import Flask, request, render_template, redirect, url_for, abort # application WSGI
import datetime
index_demo.html
dans le dossier templates
html:5
puis dans la balise
<body>
<p> heure = {{ h }} , minute = {{ m }}, seconde = {{ sec }}</p>
<br>
<a href="/">home</a>
Il faut corriger le nom de la variable : remplacer m par min
app.py
), il n’y a que des fonctions sauf
app.run
qui lance l’applicationnous 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'}
{ ]
ajouter ce tableau au début du fichier d’application flask après avoir importé les bibliothèques
créer une route /etudiant/show
qui appelle la
fonction show_etudiants
à l’intérieur du dossier templates, créer un dossier
etudiant
; dans le dossier templates/etudiant/
créer une vue (un fichier) show_etudiant.html
dans la fonction show_etudiants
, passer en paramètre
la liste liste_etudiants
avec comme nom
etudiants
afficher la liste des étudiants dans le fichier
templates/etudiant/show_etudiant.html
<h1>listes des étudiants</h1>
{{ etudiants }}
templates/index_demo.html
<br>
<a href="/etudiant/show">etudiants</a>
<table>
{% for etudiant in etudiants %}<tr>
<td>{{ etudiant }}</td>
</tr>
{% endfor %}</table>
<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>
tester avec un tableau de dictionnaire d’étudiant vide dans le
fichier app.py
afficher 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)
/etudiant/edit
et
/etudiant/delete
.au bout des 2 routes ajouter un paramètre : l’identifiant de
l’étudiant ?id=
suivi de la valeur de l’identifiant de
l’étudiant.
ajouter un lien pour ajouter un étudiant avant l’affichage du tableau
<a href="/etudiant/add" >ajouter un étudiant</a>
....
<td>
<a href="/etudiant/edit?id={{ etudiant.id }}" class="btn btn-success">editer</a>
<a href="/etudiant/delete?id={{ etudiant.id }}" class="btn btn-success">supprimer</a>
</td>
/etudiant/add
,
/etudiant/delete
et /etudiant/edit
dans le
fichier de l’application flask associées à 3 fonctions
add_etudiant
, delete_etudiant
et
edit_etudiant
@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')
voici le code HTML généré par ChatGPT 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.0">
<title>Formulaire d'Étudiant</title>
<!-- Inclure Bootstrap 5 CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.7.0/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-4">
<h1>Formulaire d'Étudiant</h1>
<form>
<!-- Champs pour saisir les informations de l'étudiant -->
<div class="mb-3">
<label for="nom" class="form-label">Nom de l'étudiant :</label>
<input type="text" class="form-control" id="nom" placeholder="Entrez le nom de l'étudiant" required>
</div>
<div class="mb-3">
<label for="groupe" class="form-label">Groupe de l'étudiant :</label>
<select class="form-select" id="groupe" required>
<option value="A1">A1</option>
<option value="A2">A2</option>
<option value="B1">B1</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Enregistrer</button>
</form>
</div>
<!-- Inclure Bootstrap 5 JS (pour les fonctionnalités supplémentaires) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.7.0/dist/js/bootstrap.min.js"></script>
</body>
</html>
créer 2 templates etudiant/add_etudiant.html
et
etudiant/edit_etudiant.html
dans les 2 fonctions delete_etudiant
et
edit_etudiant
, afficher à l’aide de l’instruction
print
dans le terminal le paramètre reçu de nom
id
. Utiliser la fonction
print(request.args)
.
pourdelete_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
delete_etudiant
faire une
redirection sur la route show_etudiants
avec l’instruction
:return redirect('/etudiant/show')
delete_etudiant
et edit_etudiant
id=request.args.get('id')
='paramètre dans l URL : '+id
messageprint(message)
* Pour récupérer les paramètres dans l’URL d’une
page HTML (méthode GET
), utiliser la méthode de l’objet
request : request.args.get
avec comme clé le nom
du paramètre
edit_etudiant
, ajouter le code
ci-dessous puis passerid=request.args.get('id')
if id != None and id.isnumeric():
= int(id)
indice =liste_etudiants[indice-1]
etudiantelse:
=[] etudiant
edit_etudiant.html
. Afficher dans chaque champ
input
de ce template la valeur de l’information concernant
l’étudiant (id, nom , groupe) .code branche 2 – étape 23 tester et modifier le code sur github
/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')
ajouter dans les balises <form>
des 2
formulaires des templates les attributs
action="/etudiant/add" method="post"
ou les attributs
action="/etudiant/edit" method="post"
indiquer 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']
afficher dans le terminal dans les 2 fonctions
valid_add_etudiant
et valid_edit_etudiant
les
paramètres reçu de chaque formulaire
print(request.form)
créer un message avec les informations pour ajouter un étudiant
= request.form.get('nom')
nom = request.form.get('groupe')
groupe = 'nom :'+nom+' - groupe :'+groupe
message print(message)
tester et modifier l’erreur : ChatGPT a oublier l’attribut
name=
dans les balises <input>
et
<select>
créer un message avec les informations pour modifier un étudiant
id = request.form.get('id')
= request.form.get('nom')
nom = request.form.get('groupe')
groupe = 'nom :'+nom+' - groupe :'+groupe+' pour l etudiant d identifiant :'+id
message print(message)
<input type="hidden" name="id" value="{{ etudiant.id }}" >
Dans ce formulaire, il manque l’attribut
value={{etudiant.nom}}
dans la balise
<input>
pour que ce champ soit initialisé avec le nom
de l’étudiant à éventuellement modifier.
Afficher la valeur du groupe
{{etudiant.groupe}}
; pour la liste déroulante, c’est plus
compliqué, le code est présenté dans le tp suivant.
GET
, utiliser la méthode de l’objet
request : request.args.get
POST
, utiliser la méthode de l’objet
request : request.form.get
/hello
et la fonction
hello_world
; associer la route /
à la
fonction show_etudiants
/heure
et la fonction
heure
Il n’est pas possible dans le dossier templates
d’utiliser des fichiers CSS des images ….
static
Les fichiers STATIC sont tous des fichiers dont le contenu ne changent jamais : les fichiers CSS (vos styles, bootstrap), les images, les fichiers javascript
Ce dossier s’appelle aussi public dans d’autres framework(s) (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') }}
show_etudiants.html
(gabarits) avec les liens
ci-dessous<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
<!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>
<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 %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for categorie, message in messages %}<div role="alert" class="alert {{ categorie }}">
<strong>{{ message }}</strong>
Information : </div>
{% endfor %}
{% endif %} {% endwith %}
flash(message, 'alert-warning')
flash(message, 'alert-success')
= [
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', groupes=liste_groupes)
<td>{{ etudiant.id }}</td><td>{{ etudiant.nom }}</td><td>{{ etudiant.groupe }}</td>
et la récupération des données dans les fonctions appellées lors de la validation des formulaires
= request.form.get('nom')
nom = request.form.get('id_groupe')
id_groupe = 'nom :'+nom+' - id_groupe :' + id_groupe
message print(message)
id = request.form.get('id')
= request.form.get('nom')
nom = request.form.get('id_groupe')
id_groupe = 'nom :'+nom+' - id_groupe :' + id_groupe + ' pour l etudiant d identifiant :' + id
message print(message)
en cas de problème avec pycharm (blocage) : supprimer le dossier
.cache/jetbrains/pycharm
probleme version
python