Rendu de templates Flask
Concaténer des chaînes HTML dans du code Python est à la fois fastidieux et dangereux (exposé aux vulnérabilités XSS). Flask intègre le moteur de templates Jinja2 pour résoudre ce problème.
Les modèles vous permettent de séparer la logique métier de la présentation des pages, ce qui permet d'écrire du code plus sûr et plus facile à maintenir.
Notions de base de render_template
render_template()C'est la fonction de rendu de modèle la plus couramment utilisée dans Flask.
Son premier paramètre est le nom du fichier de modèle, et les arguments nommés suivants sont transmis au modèle en tant que variables.
Exemple
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
# Rendre le modèle templates/index.html, en passant les variables title et name
return render_template("index.html", title=EXEMPLE Accueil, name="World")
@app.route("/user/<username>")
def profile(username):
# Transmettre le nom d'utilisateur depuis l'URL au modèle
return render_template("user.html", username=username, posts=[
{"title": Introduction à Flask, "date": "2026-05-01"},
{"title": Modèle Jinja2, "date": "2026-05-10"},
])
Les fichiers de modèle sont placés dans le répertoire du projettemplates/Dans le dossier :
example-flask-test/
├── app.py
└── templates/
├── index.html
└── user.html
Le contenu de index.html est :
Exemple (index.html)
<!DOCTYPE html>
<html>
<head>
<title>{{ title }} - EXEMPLE</title>
</head>
<body>
<h1>{{ title }} </h1>
<p>Bonjour {{ name }}.</p>
</body>
</html>
Visitezhttp://127.0.0.1:5000/, le résultat de sortie est :

Syntaxe de base de Jinja2
Trois syntaxes fondamentales dans les modèles Jinja2 :
| Syntaxe | Objectif | Exemple |
|---|---|---|
| {{ ... }} | Afficher les valeurs des variables, échapper automatiquement le HTML | {{ username }} |
| {% ... %} | Instructions de contrôle (if, for, block, etc.) | {% if user %} |
| {# ... #} | Commentaires, n'apparaîtront pas dans le résultat rendu | {# Ceci est un commentaire #} |
Exemple de modèle
Exemple (user.html)
<!DOCTYPE html>
<html>
<head>
<title>{{ username }} - EXEMPLE</title>
</head>
<body>
<h1>Page d'accueil personnelle de {{ username }}</h1>
<!-- Conditionnel : si la liste des articles est vide, afficher un message d'invite -->
{% if posts %}
<h2>Articles récents :</h2>
<ul>
<!-- Parcourir la liste des articles -->
{% for post in posts %}
<!-- loop.index est une variable intégrée de Jinja2, commençant à 1 -->
<li>{{ loop.index }}. {{ post.title }} ({{ post.date }})</li>
{% endfor %}
</ul>
{% else %}
<p>Aucun article pour le moment</p>
{% endif %}
<!-- Utilisation du filtre : upper convertit le texte en majuscules -->
<p>Nom d'utilisateur en majuscules : {{ username|upper }}</p>
</body>
</html>
Filtres courants
Les filtres servent à modifier le format de sortie des variables, à l'aide du symbole pipe.|Appel.
| Filter | Fonction | Exemple | Sortie |
|---|---|---|---|
| upper | Convertir en majuscules | {{ "hello"|upper }} | HELLO |
| lower | Convertir en minuscules | {{ "HELLO"|lower }} | bonjour |
| title | Mettre la première lettre en majuscule | {{ "hello world"|title }} | Hello World |
| longueur | Obtenir la longueur | {{ [1,2,3]|length }} | 3 |
| default | Définir la valeur par défaut | {{ name|default("anonymous") }} | Anonyme (lorsque name est vide) |
| safe | Marquer comme HTML sécurisé (sans échappement) | {{ "Gras"|safe }} | Rendu en texte gras |
| join | Joindre la liste | {{ ["a","b"]|join(",") }} | a,b |
Avertissement de sécurité:safeLe filtre safe désactive l'échappement automatique ; ne l'utilisez que lorsque vous faites absolument confiance à la source des données. Ne l'utilisez jamais pour les entrées utilisateur.safe。
Échappement automatique — Protection XSS
Jinja2 échappe le HTML par défaut sur toutes les sorties de variables ; il s'agit d'une défense essentielle pour la sécurité web.
Par exemple, si le nom d'utilisateur soumis par l'utilisateur est<script>alert("xss")</script>, lors du rendu du modèle, il est automatiquement converti en texte sûr :
<!-- 模板中直接使用变量 -->
<p>{{ username }}</p>
<!-- 渲染结果(HTML 特殊字符已被转义) -->
<p>&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;</p>
L'échappement s'applique à.html、.htm、.xml、.xhtml、.svgLe fichier de modèle à la fin.
Héritage de modèle — élimination du code dupliqué
L'héritage de modèle est l'une des fonctionnalités les plus puissantes de Jinja2. Il vous permet de définir une "mise en page de base", puis de remplir le contenu via des modèles enfants.
Cela évite de réécrire sans cesse les parties communes telles que les en-têtes, la navigation, les pieds de page, etc. sur chaque page.
Modèle de base (modèle parent)
Exemple
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}EXAMPLE Flask Tutorial{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<header>
<h1>EXEMPLE Tutoriel Flask</h1>
<nav>
<a href="/">Accueil</a> |
<a href="/about">À propos</a>
</nav>
</header>
<main>
<!-- le bloc est une zone de remplacement que les templates enfants peuvent remplir ou surcharger -->
{% block content %}{% endblock %}
</main>
<footer>
<p>© 2026 example.com</p>
</footer>
</body>
</html>
Template enfant (hérite du template parent)
Exemple
{% extends "base.html" %}
<!-- Surcharge le bloc title du template parent -->
{% block title %}EXAMPLE Tutoriel - Accueil{% endblock %}
<!-- Remplit le bloc content du template parent -->
{% block content %}
<h2>Bienvenue sur EXAMPLE</h2>
<p>{{ greeting }}</p>
{% if user %}
<p>Utilisateur actuel : {{ user }}</p>
{% else %}
<p><a href="/login">Veuillez d'abord vous connecter</a></p>
{% endif %}
{% endblock %}
| Balises | Fonction |
|---|---|
| {% extends "base.html" %} | Déclare que le template actuel hérite de base.html (à placer sur la première ligne) |
| {% block name %}...{% endblock %} | Définir un bloc pouvant être remplacé par les modèles enfants |
| {{ super() }} | Appeler le contenu du bloc du modèle parent portant le même nom à l'intérieur du bloc du modèle enfant. |
Après avoir utilisé l'héritage de modèles, il vous suffit de modifierbase.htmlà un seul endroit, et les parties communes de toutes les pages (telles que la navigation, le pied de page) seront automatiquement mises à jour.
Objets intégrés dans les modèles
Les objets Flask suivants peuvent être utilisés directement dans les modèles sans être passés viarender_template()Passez :
| Object | Description | Exemple d'utilisation dans un modèle |
|---|---|---|
| request | Objet de requête actuel | {{ request.path }} |
| session | Données de session actuelles | {{ session.get("username") }} |
| g | Variables globales au niveau de la requête | {{ g.user }} |
| config | Configuration de l'application | {{ config["APP_NAME"] }} |
| url_for() | Fonction de génération d'URL | {{ url_for("index") }} |
| get_flashed_messages() | Obtenir les messages flash | {% for msg in get_flashed_messages() %}... |
Inclure d'autres modèles — include
Utilisation{% include %}Vous pouvez intégrer un autre modèle dans un modèle :
Exemple
<nav style="background:#f0f0f0;padding:10px;">
<a href="/">Accueil</a> |
<a href="/posts">Articles</a> |
<a href="/about">À propos</a>
</nav>
Exemple
<!DOCTYPE html>
<html>
<head><title>Page</title></head>
<body>
{% include "_navbar.html" %}
<h1>Contenu de la page</h1>
<p>Ceci est le contenu principal de la page.</p>
</body>
</html>
Bonnes pratiques: L'héritage de template (extends) est utilisé pour la réutilisation de la mise en page au niveau de la page,includeUtilisé pour la réutilisation du code au niveau des composants. Les composants réutilisables tels que les barres de navigation et les barres latérales sont adaptés à include.
Exemple complet : page d'accueil du blog
Intégrez les connaissances ci-dessus dans un scénario concret :
Exemple
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
# Simuler les données d'articles dans la base de données.
articles = [
{"id": 1, "title": Guide de démarrage de Flask, "author": "example", "views": 1024},
{"id": 2, "title": Les templates Jinja2 expliqués, "author": "admin", "views": 512},
{"id": 3, "title": Conception d'API RESTful, "author": "example", "views": 256},
]
return render_template("blog.html", articles=articles)
Exemple
{% extends "base.html" %}
{% block title %}EXEMPLE Blog{% endblock %}
{% block content %}
<h2>Derniers articles</h2>
{% if articles %}
{% for article in articles %}
<!-- Ajouter différents styles en fonction du nombre de vues -->
<div class="article" {% if article.views > 1000 %}style="background:#fff3cd;"{% endif %}>
<h3>{{ article.title }}</h3>
<p>Auteur : {{ article.author }} | Vues : {{ article.views }}</p>
<!-- Utilisez la variable de boucle pour créer un séparateur -->
{% if not loop.last %}
<hr>
{% endif %}
</div>
{% endfor %}
{% else %}
<p>Aucun article pour le moment, veuillez revenir plus tard.</p>
{% endif %}
{% endblock %}
Variables spéciales de Jinja2
| Variable | Description |
|---|---|
| loop.index | Index actuel de la boucle, commence à 1 |
| loop.index0 | Index actuel de la boucle, commence à 0 |
| loop.first | Indique s'il s'agit de la première itération de la boucle |
| loop.last | Indique s'il s'agit de la dernière itération de la boucle |
| loop.length | Longueur totale de la séquence |