Recherche de site Web

Comment créer une application web en utilisant Flask en Python 3


L'auteur a choisi le Fonds Libre et Open Source pour recevoir un don dans le cadre du programme Write for DOnations.

Introduction

Flask est un petit et léger framework web Python qui fournit des outils et des fonctionnalités utiles qui rendent la création d'applications web en Python plus facile. Il offre aux développeurs de la flexibilité et est un framework plus accessible pour les nouveaux développeurs puisque vous pouvez créer une application web rapidement en utilisant seulement un seul fichier Python. Flask est également extensible et ne force pas une structure de répertoire particulière ni ne nécessite de code standard compliqué avant de commencer.

Dans le cadre de ce tutoriel, vous utiliserez l'outil Bootstrap pour styliser votre application afin qu'elle soit plus attrayante visuellement. Bootstrap vous aidera à intégrer des pages web responsives dans votre application web, de sorte qu'elle fonctionne également bien sur les navigateurs mobiles sans avoir à écrire votre propre code HTML, CSS et JavaScript pour atteindre ces objectifs. L'outil vous permettra de vous concentrer sur l'apprentissage du fonctionnement de Flask.

Flask utilise le moteur de templating Jinja pour construire dynamiquement des pages HTML en utilisant des concepts Python familiers tels que des variables, des boucles, des listes, etc. Vous utiliserez ces templates dans le cadre de ce projet.

Dans ce tutoriel, vous allez créer un petit blog web en utilisant Flask et SQLite en Python 3. Les utilisateurs de l'application peuvent consulter tous les articles de votre base de données et cliquer sur le titre d'un article pour voir son contenu, avec la possibilité d'ajouter un nouvel article à la base de données et de modifier ou supprimer un article existant.

Simplifiez le déploiement des applications Flask avec la plateforme d'applications DigitalOcean. Déployez Flask directement depuis GitHub en quelques minutes.

Conditions préalables

Avant de commencer à suivre ce guide, vous aurez besoin de :

  • Un environnement de programmation Python 3 local, suivez le tutoriel pour votre distribution dans la série Comment installer et configurer un environnement de programmation local pour Python 3 pour votre machine locale. Dans ce tutoriel, nous appellerons notre répertoire de projet flask_blog.
  • Une compréhension des concepts de Python 3, tels que les types de données, les instructions conditionnelles, les boucles for, les fonctions et d'autres concepts similaires. Si vous n'êtes pas familier avec Python, consultez notre série Comment coder en Python 3.

Étape 1 — Installation de Flask

Dans cette étape, vous allez activer votre environnement Python et installer Flask en utilisant le programme d'installation de paquets pip.

Si vous n'avez pas encore activé votre environnement de programmation, assurez-vous d'être dans votre répertoire de projet (flask_blog) et utilisez la commande suivante pour activer l'environnement :

  1. source env/bin/activate

Une fois que votre environnement de programmation est activé, votre invite aura maintenant un préfixe env qui pourrait ressembler à ceci :

Ce préfixe indique que l'environnement env est actuellement actif, ce qui pourrait avoir un autre nom selon la manière dont vous l'avez nommé lors de sa création.

Remarque : Vous pouvez utiliser Git, un système de contrôle de version, pour gérer et suivre efficacement le processus de développement de votre projet. Pour apprendre à utiliser Git, vous voudrez peut-être consulter notre article Introduction à l'installation, à l'utilisation et aux branches de Git.

Si vous utilisez Git, il est préférable d'ignorer le nouveau répertoire env dans votre fichier .gitignore afin d'éviter de suivre des fichiers non liés au projet.

Maintenant, vous allez installer des packages Python et isoler le code de votre projet du système d'installation Python principal. Vous ferez cela en utilisant pip et python.

Pour installer Flask, exécutez la commande suivante :

  1. pip install flask

Une fois l'installation terminée, exécutez la commande suivante pour confirmer l'installation :

  1. python -c "import flask; print(flask.__version__)"

Vous utilisez l'interface de ligne de commande python avec l'option -c pour exécuter du code Python. Ensuite, vous importez le paquet flask avec import flask; puis imprimez la version de Flask, qui est fournie via la variable flask.__version__.

La sortie sera un numéro de version similaire au suivant :

1.1.2

Vous avez créé le dossier du projet, un environnement virtuel et installé Flask. Vous êtes maintenant prêt à passer à la configuration de votre application de base.

Étape 2 — Création d'une application de base

Maintenant que vous avez configuré votre environnement de programmation, vous allez commencer à utiliser Flask. Dans cette étape, vous allez créer une petite application web à l'intérieur d'un fichier Python et l'exécuter pour démarrer le serveur, qui affichera des informations dans le navigateur.

Dans votre répertoire flask_blog, ouvrez un fichier nommé hello.py pour l'éditer, utilisez nano ou votre éditeur de texte préféré :

  1. nano hello.py

Ce fichier hello.py servira d'exemple minimal de la façon de gérer les requêtes HTTP. À l'intérieur, vous importerez l'objet Flask et créerez une fonction qui renvoie une réponse HTTP. Écrivez le code suivant à l'intérieur de hello.py:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello, World!'

Dans le bloc de code précédent, vous importez d'abord l'objet Flask du package flask. Vous l'utilisez ensuite pour créer votre instance d'application Flask avec le nom app. Vous passez la variable spéciale __name__ qui contient le nom du module Python actuel. Elle est utilisée pour indiquer à l'instance où elle se trouve — vous en avez besoin car Flask configure certains chemins en arrière-plan.

Une fois que vous avez créé l'instance app, vous l'utilisez pour gérer les requêtes web entrantes et envoyer des réponses à l'utilisateur. @app.route est un décorateur qui transforme une fonction Python ordinaire en une fonction de vue Flask, qui convertit la valeur de retour de la fonction en une réponse HTTP à afficher par un client HTTP, tel qu'un navigateur web. Vous passez la valeur '/' à @app.route() pour signifier que cette fonction répondra aux requêtes web pour l'URL /, qui est l'URL principale.

La fonction de vue hello() renvoie la chaîne de caractères 'Hello, World!' en réponse.

Enregistrez et fermez le fichier.

Pour exécuter votre application web, vous devez d'abord indiquer à Flask où trouver l'application (le fichier hello.py dans votre cas) avec la variable d'environnement FLASK_APP :

  1. export FLASK_APP=hello

Ensuite, exécutez-le en mode développement avec la variable d'environnement FLASK_ENV :

  1. export FLASK_ENV=development

Enfin, exécutez l'application en utilisant la commande flask run :

  1. flask run

Une fois que l'application est en cours d'exécution, la sortie sera quelque chose comme ceci :

 * Serving Flask app "hello" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 813-894-335

La sortie précédente contient plusieurs informations, telles que :

  • Le nom de l'application que vous exécutez.
  • L'environnement dans lequel l'application est en cours d'exécution.
  • Mode débogage : activé signifie que le débogueur Flask est en cours d'exécution. Cela est utile lors du développement car cela nous donne des messages d'erreur détaillés quand quelque chose ne va pas, ce qui facilite le dépannage.
  • L'application fonctionne localement sur l'URL http://127.0.0.1:5000/, 127.0.0.1 est l'adresse IP qui représente le localhost de votre machine et :5000 est le numéro de port.

Ouvrez un navigateur et tapez l'URL http://127.0.0.1:5000/, vous recevrez la chaîne Hello, World! en réponse, ce qui confirme que votre application fonctionne avec succès.

Avertissement Flask utilise un serveur web simple pour servir notre application dans un environnement de développement, ce qui signifie également que le débogueur Flask est en cours d'exécution pour faciliter la capture d'erreurs. Ce serveur de développement ne doit pas être utilisé dans un déploiement en production. Consultez la page des Options de Déploiement dans la documentation Flask pour plus d'informations, vous pouvez également consulter ce tutoriel de déploiement Flask.

Vous pouvez maintenant laisser le serveur de développement en cours d'exécution dans le terminal et ouvrir une autre fenêtre de terminal. Déplacez-vous dans le dossier du projet où se trouve hello.py, activez l'environnement virtuel, définissez les variables d'environnement FLASK_ENV et FLASK_APP, et continuez aux étapes suivantes. (Ces commandes sont énumérées plus tôt dans cette étape.)

Remarque : Lors de l'ouverture d'un nouveau terminal, il est important de se souvenir d'activer l'environnement virtuel et de définir les variables d'environnement FLASK_ENV et FLASK_APP.

Alors qu'un serveur de développement d'application Flask est déjà en cours d'exécution, il n'est pas possible de lancer une autre application Flask avec la même commande flask run. Cela est dû au fait que flask run utilise par défaut le numéro de port 5000, et une fois qu'il est pris, il devient indisponible pour exécuter une autre application, vous recevriez donc une erreur similaire à ce qui suit :

OSError: [Errno 98] Address already in use

Pour résoudre ce problème, arrêtez soit le serveur qui fonctionne actuellement via CTRL+C, puis exécutez à nouveau flask run, soit si vous souhaitez exécuter les deux en même temps, vous pouvez passer un numéro de port différent à l'argument -p, par exemple, pour exécuter une autre application sur le port 5001, utilisez la commande suivante :

  1. flask run -p 5001

Vous avez maintenant une petite application web Flask. Vous avez exécuté votre application et affiché des informations dans le navigateur web. Ensuite, vous utiliserez des fichiers HTML dans votre application.

Étape 3 — Utiliser des modèles HTML

Actuellement, votre application n'affiche qu'un simple message sans aucun HTML. Les applications web utilisent principalement HTML pour afficher des informations pour le visiteur, vous allez donc maintenant travailler à l'incorporation de fichiers HTML dans votre application, qui peuvent être affichés sur le navigateur web.

Flask fournit une fonction d'assistance render_template() qui permet d'utiliser le moteur de template Jinja. Cela rendra la gestion du HTML beaucoup plus facile en écrivant votre code HTML dans des fichiers .html, tout en utilisant de la logique dans votre code HTML. Vous utiliserez ces fichiers HTML, (templates), pour construire toutes les pages de votre application, comme la page principale où vous afficherez les articles de blog actuels, la page de l'article de blog, la page où l'utilisateur peut ajouter un nouvel article, et ainsi de suite.

À cette étape, vous allez créer votre application Flask principale dans un nouveau fichier.

Tout d'abord, dans votre répertoire flask_blog, utilisez nano ou votre éditeur préféré pour créer et modifier votre fichier app.py. Cela contiendra tout le code que vous utiliserez pour créer l'application de blog:

  1. nano app.py

Dans ce nouveau fichier, vous importerez l'objet Flask pour créer une instance d'application Flask comme vous l'avez fait précédemment. Vous importerez également la fonction d'aide render_template() qui vous permet de rendre des fichiers de modèles HTML qui se trouvent dans le dossier templates que vous êtes sur le point de créer. Le fichier aura une seule fonction de vue qui sera responsable de la gestion des requêtes à la route principale /. Ajoutez le contenu suivant :

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

La fonction de vue index() renvoie le résultat de l'appel à render_template() avec index.html comme argument, ce qui indique à render_template() de chercher un fichier appelé index.html dans le dossier des modèles. Ni le dossier ni le fichier n'existent encore, vous obtiendrez une erreur si vous exécutez l'application à ce stade. Vous allez néanmoins l'exécuter pour vous familiariser avec cette exception couramment rencontrée. Vous corrigerez ensuite cela en créant le dossier et le fichier nécessaires.

Enregistrez et quittez le fichier.

Arrêtez le serveur de développement dans votre autre terminal qui exécute l'application hello avec CTRL+C.

Avant de lancer l'application, assurez-vous de spécifier correctement la valeur de la variable d'environnement FLASK_APP, car vous n'utilisez plus l'application hello :

  1. export FLASK_APP=app
  2. flask run

Ouvrir l'URL http://127.0.0.1:5000/ dans votre navigateur entraînera l'affichage de la page de débogage vous informant que le modèle index.html n'a pas été trouvé. La ligne principale dans le code qui était responsable de cette erreur sera mise en évidence. Dans ce cas, il s'agit de la ligne return render_template('index.html').

Si vous cliquez sur cette ligne, le débogueur révélera plus de code afin que vous ayez plus de contexte pour vous aider à résoudre le problème.

Pour corriger cette erreur, créez un répertoire appelé templates à l'intérieur de votre répertoire flask_blog. Ensuite, à l'intérieur, ouvrez un fichier appelé index.html pour l'éditer :

  1. mkdir templates
  2. nano templates/index.html

Ensuite, ajoutez le code HTML suivant à l'intérieur de index.html :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FlaskBlog</title>
</head>
<body>
   <h1>Welcome to FlaskBlog</h1>
</body>
</html>

Enregistrez le fichier et utilisez votre navigateur pour naviguer à nouveau à l'adresse http://127.0.0.1:5000/, ou rafraîchissez la page. Cette fois, le navigateur devrait afficher le texte Bienvenue sur FlaskBlog dans une balise <h1>.

En plus du dossier templates, les applications web Flask ont également généralement un dossier static pour héberger des fichiers statiques, tels que des fichiers CSS, des fichiers JavaScript et des images que l'application utilise.

Vous pouvez créer un fichier de feuille de style style.css pour ajouter du CSS à votre application. Tout d'abord, créez un répertoire appelé static à l'intérieur de votre répertoire principal flask_blog :

  1. mkdir static

Ensuite, créez un autre répertoire appelé css à l'intérieur du répertoire static pour héberger les fichiers .css. Cela se fait généralement pour organiser les fichiers statiques dans des dossiers dédiés ; ainsi, les fichiers JavaScript vivent généralement dans un répertoire appelé js, les images sont placées dans un répertoire appelé images (ou img), et ainsi de suite. La commande suivante créera le répertoire css à l'intérieur du répertoire static :

  1. mkdir static/css

Ensuite, ouvrez un fichier style.css dans le répertoire css pour édition :

  1. nano static/css/style.css

Ajoutez la règle CSS suivante à votre fichier style.css :

h1 {
    border: 2px #eee solid;
    color: brown;
    text-align: center;
    padding: 10px;
}

Le code CSS ajoutera une bordure, changera la couleur en marron, centrera le texte et ajoutera un peu de rembourrage aux balises <h1>.

Enregistrez et fermez le fichier.

Ensuite, ouvrez le fichier modèle index.html pour le modifier :

  1. nano templates/index.html

Vous ajouterez un lien vers le fichier style.css à l'intérieur de la section <head> du fichier modèle index.html :

. . .
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}">
    <title>FlaskBlog</title>
</head>
. . .

Ici, vous utilisez la fonction d'assistance url_for() pour générer l'emplacement approprié du fichier. Le premier argument spécifie que vous liez à un fichier statique et le deuxième argument est le chemin du fichier à l'intérieur du répertoire statique.

Enregistrez et fermez le fichier.

En actualisant la page d'index de votre application, vous remarquerez que le texte Bienvenue dans FlaskBlog est désormais en marron, centré et entouré d'une bordure.

Vous pouvez utiliser le langage CSS pour styliser l'application et la rendre plus attrayante en utilisant votre propre design. Cependant, si vous n'êtes pas un designer web, ou si vous n'êtes pas familier avec le CSS, alors vous pouvez utiliser le toolkit Bootstrap, qui fournit des composants faciles à utiliser pour styliser votre application. Dans ce projet, nous utiliserons Bootstrap.

Vous avez peut-être deviné que créer un autre modèle HTML signifierait répéter la plupart du code HTML que vous avez déjà écrit dans le modèle index.html. Vous pouvez éviter la répétition de code inutile grâce à un fichier modèle de base, dont tous vos fichiers HTML hériteront. Voir Héritage des modèles dans Jinja pour plus d'informations.

Pour créer un modèle de base, commencez par créer un fichier appelé base.html dans votre répertoire templates :

  1. nano templates/base.html

Tapez le code suivant dans votre modèle base.html :

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <title>{% block title %} {% endblock %}</title>
  </head>
  <body>
    <nav class="navbar navbar-expand-md navbar-light bg-light">
        <a class="navbar-brand" href="{{ url_for('index')}}">FlaskBlog</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav">
            <li class="nav-item active">
                <a class="nav-link" href="#">About</a>
            </li>
            </ul>
        </div>
    </nav>
    <div class="container">
        {% block content %} {% endblock %}
    </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>

Enregistrez et fermez le fichier une fois que vous avez terminé de l'éditer.

La majeure partie du code dans le bloc précédent est du HTML standard et du code requis pour Bootstrap. Les balises <meta> fournissent des informations pour le navigateur web, la balise <link> lie les fichiers CSS de Bootstrap, et les balises <script> sont des liens vers le code JavaScript qui permet quelques fonctionnalités supplémentaires de Bootstrap, consultez la documentation de Bootstrap pour en savoir plus.

Cependant, les parties mises en évidence suivantes sont spécifiques au moteur de template Jinja:

  • {% block title %} {% endblock %}: Un bloc qui sert de zone de remplacement pour un titre, que vous utiliserez plus tard dans d'autres modèles pour donner un titre personnalisé à chaque page de votre application sans avoir à réécrire à chaque fois l'intégralité de la section <head>.
  • {{ url_for('index')}}: Un appel de fonction qui renverra l'URL pour la fonction de vue index(). Cela est différent de l'appel url_for() que vous avez utilisé auparavant pour lier un fichier CSS statique, car il ne prend qu'un seul argument, qui est le nom de la fonction de vue, et se lie à la route associée à la fonction plutôt qu'à un fichier statique.
  • {% block content %} {% endblock %}: Un autre bloc qui sera remplacé par du contenu en fonction du modèle enfant (les modèles qui héritent de base.html) qui l'overridera.

Maintenant que vous avez un modèle de base, vous pouvez en tirer parti en utilisant l'héritage. Ouvrez le fichier index.html :

  1. nano templates/index.html

Puis remplacez son contenu par ce qui suit :

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>
{% endblock %}

Dans cette nouvelle version du modèle index.html, vous utilisez la balise {% extends %} pour hériter du modèle base.html. Vous l'étendez ensuite en remplaçant le bloc content dans le modèle de base par ce qui se trouve à l'intérieur du bloc content dans le bloc de code précédent.

Ce bloc content contient une balise <h1> avec le texte Bienvenue sur FlaskBlog à l'intérieur d'un bloc title, qui remplace à son tour le bloc title original dans le template base.html par le texte Bienvenue sur FlaskBlog. De cette façon, vous évitez de répéter le même texte deux fois, car cela fonctionne à la fois comme un titre pour la page et comme un en-tête qui apparaît sous la barre de navigation héritée du template de base.

L'héritage de modèles vous permet également de réutiliser le code HTML que vous avez dans d'autres modèles (dans ce cas base.html) sans avoir à le répéter chaque fois qu'il est nécessaire.

Enregistrez et fermez le fichier, puis actualisez la page d'index dans votre navigateur. Vous verrez votre page avec une barre de navigation et un titre stylisé.

Vous avez utilisé des modèles HTML et des fichiers statiques dans Flask. Vous avez également utilisé Bootstrap pour commencer à affiner l'apparence de votre page et un modèle de base pour éviter la répétition du code. Dans l'étape suivante, vous allez configurer une base de données qui stockera les données de votre application.

Étape 4 — Configuration de la base de données

Dans cette étape, vous allez configurer une base de données pour stocker des données, c'est-à-dire les articles de blog pour votre application. Vous allez également remplir la base de données avec quelques exemples.

Vous utiliserez un fichier de base de données SQLite pour stocker vos données car le module sqlite3, que nous utiliserons pour interagir avec la base de données, est facilement disponible dans la bibliothèque standard de Python. Pour plus d'informations sur SQLite, consultez ce tutoriel.

Tout d'abord, parce que les données dans SQLite sont stockées dans des tables et des colonnes, et puisque vos données se composent principalement d'articles de blog, vous devez d'abord créer une table appelée posts avec les colonnes nécessaires. Vous allez créer un fichier .sql contenant des commandes SQL pour créer la table posts avec quelques colonnes. Vous utiliserez ensuite ce fichier pour créer la base de données.

Ouvrez un fichier appelé schema.sql dans votre répertoire flask_blog :

  1. nano schema.sql

Tapez les commandes SQL suivantes dans ce fichier :

DROP TABLE IF EXISTS posts;

CREATE TABLE posts (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    title TEXT NOT NULL,
    content TEXT NOT NULL
);

Enregistrez et fermez le fichier.

La première commande SQL est DROP TABLE IF EXISTS posts;, cela supprime toutes les tables existantes nommées posts afin que vous n'ayez pas de comportement confus. Notez que cela supprimera tout le contenu que vous avez dans la base de données chaque fois que vous utiliserez ces commandes SQL, donc assurez-vous de ne pas écrire de contenu important dans l'application web jusqu'à ce que vous ayez terminé ce tutoriel et expérimenté avec le résultat final. Ensuite, CREATE TABLE posts est utilisé pour créer la table posts avec les colonnes suivantes :

  • id : Un entier qui représente une clé primaire, il se verra attribuer une valeur unique par la base de données pour chaque entrée (c'est-à-dire un article de blog).
  • créé: L'heure à laquelle l'article de blog a été créé. NOT NULL signifie que cette colonne ne doit pas être vide et que la valeur par défaut est le CURRENT_TIMESTAMP, qui est l'heure à laquelle le post a été ajouté à la base de données. Tout comme id, vous n'avez pas besoin de spécifier une valeur pour cette colonne, car elle sera automatiquement renseignée.
  • titre: Le titre du post.
  • Le contenu de l'article.

Maintenant que vous avez un schéma SQL dans le fichier schema.sql, vous l'utiliserez pour créer la base de données à l'aide d'un fichier Python qui générera un fichier de base de données SQLite .db. Ouvrez un fichier nommé init_db.py dans le répertoire flask_blog en utilisant votre éditeur préféré :

  1. nano init_db.py

Et ensuite ajoutez le code suivant.

import sqlite3

connection = sqlite3.connect('database.db')


with open('schema.sql') as f:
    connection.executescript(f.read())

cur = connection.cursor()

cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)",
            ('First Post', 'Content for the first post')
            )

cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)",
            ('Second Post', 'Content for the second post')
            )

connection.commit()
connection.close()

Vous commencez par importer le module sqlite3 puis ouvrez une connexion à un fichier de base de données nommé database.db, qui sera créé une fois que vous exécuterez le fichier Python. Ensuite, vous utilisez la fonction open() pour ouvrir le fichier schema.sql. Ensuite, vous exécutez son contenu en utilisant la méthode executescript() qui exécute plusieurs instructions SQL à la fois, ce qui créera la table posts. Vous créez un objet Cursor qui vous permet d'utiliser sa méthode execute() pour exécuter deux instructions SQL INSERT pour ajouter deux articles de blog à votre table posts. Enfin, vous validez les modifications et fermez la connexion.

Enregistrez et fermez le fichier, puis exécutez-le dans le terminal en utilisant la commande python :

  1. python init_db.py

Une fois que le fichier a terminé son exécution, un nouveau fichier appelé database.db apparaîtra dans votre répertoire flask_blog. Cela signifie que vous avez réussi à configurer votre base de données.

Dans la prochaine étape, vous allez récupérer les publications que vous avez insérées dans votre base de données et les afficher sur la page d'accueil de votre application.

Étape 5 — Affichage de tous les articles

Maintenant que vous avez configuré votre base de données, vous pouvez maintenant modifier la fonction de vue index() pour afficher tous les posts que vous avez dans votre base de données.

Ouvrez le fichier app.py pour apporter les modifications suivantes :

  1. nano app.py

Pour votre première modification, vous importerez le module sqlite3 en haut du fichier :

import sqlite3
from flask import Flask, render_template

. . .

Ensuite, vous allez créer une fonction qui crée une connexion à la base de données et la renvoie. Ajoutez-la directement après les imports :

. . .
from flask import Flask, render_template

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn

. . .

Cette fonction get_db_connection() ouvre une connexion avec le fichier de base de données database.db, puis définit l'attribut row_factory sur sqlite3.Row pour vous permettre un accès par nom aux colonnes. Cela signifie que la connexion à la base de données renverra des lignes qui se comportent comme des dictionnaires Python classiques. Enfin, la fonction retourne l'objet de connexion conn que vous utiliserez pour accéder à la base de données.

Après avoir défini la fonction get_db_connection(), modifiez la fonction index() pour qu'elle ressemble à ce qui suit :

. . .

@app.route('/')
def index():
    conn = get_db_connection()
    posts = conn.execute('SELECT * FROM posts').fetchall()
    conn.close()
    return render_template('index.html', posts=posts)

Dans cette nouvelle version de la fonction index(), vous ouvrez d'abord une connexion à la base de données à l'aide de la fonction get_db_connection() que vous avez définie précédemment. Ensuite, vous exécutez une requête SQL pour sélectionner toutes les entrées de la table posts. Vous implémentez la méthode fetchall() pour récupérer toutes les lignes du résultat de la requête ; cela renverra une liste des publications que vous avez insérées dans la base de données à l'étape précédente.

Vous fermez la connexion à la base de données en utilisant la méthode close() et retournez le résultat du rendu du modèle index.html. Vous passez également l'objet posts comme argument, qui contient les résultats que vous avez obtenus de la base de données, ce qui vous permettra d'accéder aux articles du blog dans le modèle index.html.

Avec ces modifications en place, enregistrez et fermez le fichier app.py.

Maintenant que vous avez passé les publications récupérées de la base de données au modèle index.html, vous pouvez utiliser une boucle for pour afficher chaque publication sur votre page d'accueil.

Ouvrez le fichier index.html :

  1. nano templates/index.html

Ensuite, modifiez-le pour qu'il ressemble à ceci :

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>
    {% for post in posts %}
        <a href="#">
            <h2>{{ post['title'] }}</h2>
        </a>
        <span class="badge badge-primary">{{ post['created'] }}</span>
        <hr>
    {% endfor %}
{% endblock %}

Ici, la syntaxe {% for post in posts %} est une boucle for Jinja, qui est similaire à une boucle for en Python, sauf qu'elle doit être fermée plus tard avec la syntaxe {% endfor %}. Vous utilisez cette syntaxe pour parcourir chaque élément de la liste posts qui a été passée par la fonction index() dans la ligne return render_template('index.html', posts=posts). À l'intérieur de cette boucle for, vous affichez le titre du post dans un en-tête <h2> à l'intérieur d'une balise <a> (vous utiliserez plus tard cette balise pour lier chaque post individuellement).

Vous affichez le titre en utilisant un délimiteur de variable littéral ({{ ... }}). N'oubliez pas que post sera un objet semblable à un dictionnaire, donc vous pouvez accéder au titre du post avec post['title']. Vous affichez également la date de création du post en utilisant la même méthode.

Une fois que vous avez terminé de modifier le fichier, enregistrez-le et fermez-le. Ensuite, naviguez vers la page d'index dans votre navigateur. Vous verrez les deux publications que vous avez ajoutées à la base de données sur votre page.

Maintenant que vous avez modifié la fonction de vue index() pour afficher tous les articles que vous avez dans la base de données sur la page d'accueil de votre application, vous passerez à l'affichage de chaque article sur une page unique et permettrez aux utilisateurs de se lier à chaque article individuel.

Étape 6 — Affichage d'un seul article

À cette étape, vous allez créer un nouveau itinéraire Flask avec une fonction de vue et un nouveau modèle HTML pour afficher un article de blog individuel par son identifiant.

À la fin de cette étape, l'URL http://127.0.0.1:5000/1 sera une page qui affiche le premier post (car il a l'ID 1). L'URL http://127.0.0.1:5000/ID affichera le post avec le numéro ID associé s'il existe.

Ouvrez app.py pour l'éditer :

  1. nano app.py

Puisque vous aurez besoin de récupérer un article de blog par son ID à partir de la base de données à plusieurs endroits plus tard dans ce projet, vous allez créer une fonction autonome appelée get_post(). Vous pouvez l'appeler en lui passant un ID et recevoir l'article de blog associé à l'ID fourni, ou faire en sorte que Flask réponde avec un message 404 Non Trouvé si l'article de blog n'existe pas.

Pour répondre avec une page 404, vous devez importer la fonction abort() de la bibliothèque Werkzeug, qui a été installée avec Flask, en haut du fichier :

import sqlite3
from flask import Flask, render_template
from werkzeug.exceptions import abort

. . .

Ensuite, ajoutez la fonction get_post() juste après la fonction get_db_connection() que vous avez créée à l'étape précédente :

. . .

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn


def get_post(post_id):
    conn = get_db_connection()
    post = conn.execute('SELECT * FROM posts WHERE id = ?',
                        (post_id,)).fetchone()
    conn.close()
    if post is None:
        abort(404)
    return post

. . .

Cette nouvelle fonction a un argument post_id qui détermine quel article de blog retourner.

À l'intérieur de la fonction, vous utilisez la fonction get_db_connection() pour ouvrir une connexion à la base de données et exécuter une requête SQL pour obtenir le billet de blog associé à la valeur post_id donnée. Vous ajoutez la méthode fetchone() pour obtenir le résultat et le stocker dans la variable post, puis vous fermez la connexion. Si la variable post a pour valeur None, ce qui signifie qu'aucun résultat n'a été trouvé dans la base de données, vous utilisez la fonction abort() que vous avez importée plus tôt pour répondre avec un code d'erreur 404 et la fonction terminera son exécution. En revanche, si un billet a été trouvé, vous retournez la valeur de la variable post.

Ensuite, ajoutez la fonction de vue suivante à la fin du fichier app.py :

. . .

@app.route('/<int:post_id>')
def post(post_id):
    post = get_post(post_id)
    return render_template('post.html', post=post)

Dans cette nouvelle fonction de vue, vous ajoutez une règle variable <int:post_id> pour spécifier que la partie après la barre oblique (/) est un entier positif (indiqué par le convertisseur int) que vous devez accéder dans votre fonction de vue. Flask reconnaît cela et transmet sa valeur à l'argument clé post_id de votre fonction de vue post(). Vous utilisez ensuite la fonction get_post() pour obtenir le post de blog associé à l'ID spécifié et stockez le résultat dans la variable post, que vous passez à un modèle post.html que vous allez bientôt créer.

Enregistrez le fichier app.py et ouvrez un nouveau fichier de modèle post.html pour l'éditer :

  1. nano templates/post.html

Tapez le code suivant dans ce nouveau fichier post.html. Ce sera similaire au fichier index.html, sauf qu'il affichera uniquement un seul article, en plus d'afficher également le contenu de l'article :

{% extends 'base.html' %}

{% block content %}
    <h2>{% block title %} {{ post['title'] }} {% endblock %}</h2>
    <span class="badge badge-primary">{{ post['created'] }}</span>
    <p>{{ post['content'] }}</p>
{% endblock %}

Vous ajoutez le bloc title que vous avez défini dans le modèle base.html pour faire en sorte que le titre de la page reflète le titre du post qui est affiché dans un <h2> à ce moment-là.

Enregistrez et fermez le fichier.

Vous pouvez maintenant naviguer vers les URL suivantes pour voir les deux articles que vous avez dans votre base de données, ainsi qu'une page qui informe l'utilisateur que l'article de blog demandé n'a pas été trouvé (étant donné qu'il n'y a pas d'article avec un numéro d'identification de 3 jusqu'à présent) :

http://127.0.0.1:5000/1
http://127.0.0.1:5000/2
http://127.0.0.1:5000/3

En revenant à la page d'index, vous ferez en sorte que chaque titre de publication soit lié à sa page respective. Vous ferez cela en utilisant la fonction url_for(). Tout d'abord, ouvrez le modèle index.html pour l'éditer:

  1. nano templates/index.html

Ensuite, changez la valeur de l'attribut href de # à {{ url_for('post', post_id=post['id']) }} afin que la boucle for ressemble exactement à ce qui suit :

{% for post in posts %}
    <a href="{{ url_for('post', post_id=post['id']) }}">
        <h2>{{ post['title'] }}</h2>
    </a>
    <span class="badge badge-primary">{{ post['created'] }}</span>
    <hr>
{% endfor %}

Ici, vous passez 'post' à la fonction url_for() en tant que premier argument. C'est le nom de la fonction de vue post() et comme elle accepte un argument post_id, vous lui donnez la valeur post['id']. La fonction url_for() retournera l'URL appropriée pour chaque publication en fonction de son ID.

Enregistrez et fermez le fichier.

Les liens sur la page d'index fonctionneront désormais comme prévu. Avec cela, vous avez maintenant terminé de construire la partie de l'application responsable de l'affichage des articles de blog dans votre base de données. Ensuite, vous ajouterez la possibilité de créer, modifier et supprimer des articles de blog dans votre application.

Étape 7 — Modification des publications

Maintenant que vous avez terminé d'afficher les articles de blog présents dans la base de données sur l'application web, vous devez permettre aux utilisateurs de votre application d'écrire de nouveaux articles de blog et de les ajouter à la base de données, de modifier ceux qui existent déjà et de supprimer les articles de blog inutiles.

Créer un nouveau post

Jusqu'à présent, vous avez une application qui affiche les publications dans votre base de données, mais ne propose aucun moyen d'ajouter une nouvelle publication, sauf si vous vous connectez directement à la base de données SQLite et en ajoutez une manuellement. Dans cette section, vous allez créer une page sur laquelle vous pourrez créer une publication en fournissant son titre et son contenu.

Ouvrez le fichier app.py pour l'éditer :

  1. nano app.py

Tout d'abord, vous importerez ce qui suit du cadre Flask :

  • L'objet request global pour accéder aux données de la requête entrante qui seront soumises via un formulaire HTML.
  • La fonction url_for() pour générer des URL.
  • La fonction flash() pour afficher un message lorsque une requête est traitée.
  • La fonction redirect() pour rediriger le client vers un autre emplacement.

Ajoutez les imports dans votre fichier comme suit :

import sqlite3
from flask import Flask, render_template, request, url_for, flash, redirect
from werkzeug.exceptions import abort

. . .

La fonction flash() stocke des messages flashés dans la session du navigateur du client, ce qui nécessite de définir une clé secrète. Cette clé secrète est utilisée pour sécuriser les sessions, permettant à Flask de se souvenir des informations d'une requête à l'autre, comme le passage de la page de création de nouveau post à la page d'index. L'utilisateur peut accéder aux informations stockées dans la session, mais ne peut pas les modifier à moins d'avoir la clé secrète, il est donc impératif de ne jamais permettre à quiconque d'accéder à votre clé secrète. Consultez la documentation de Flask sur les sessions pour plus d'informations.

Pour définir une clé secrète, vous ajouterez une configuration SECRET_KEY à votre application via l'objet app.config. Ajoutez-la directement après la définition de app, avant de définir la fonction de vue index() :

. . .
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your secret key'


@app.route('/')
def index():
    conn = get_db_connection()
    posts = conn.execute('SELECT * FROM posts').fetchall()
    conn.close()
    return render_template('index.html', posts=posts)

. . .

N'oubliez pas que la clé secrète doit être une longue chaîne de caractères aléatoires.

Après avoir défini une clé secrète, vous créerez une fonction de vue qui rendra un modèle affichant un formulaire que vous pouvez remplir pour créer un nouvel article de blog. Ajoutez cette nouvelle fonction en bas du fichier :

. . .

@app.route('/create', methods=('GET', 'POST'))
def create():
    return render_template('create.html')

Cela crée une route /create qui accepte à la fois les requêtes GET et POST. Les requêtes GET sont acceptées par défaut. Pour accepter également les requêtes POST, qui sont envoyées par le navigateur lors de la soumission de formulaires, vous devez passer un tuple avec les types de requêtes acceptés à l'argument methods du décorateur @app.route().

Enregistrez et fermez le fichier.

Pour créer le modèle, ouvrez un fichier appelé create.html à l'intérieur de votre dossier templates :

  1. nano templates/create.html

Ajoutez le code suivant dans ce nouveau fichier :

{% extends 'base.html' %}

{% block content %}
<h1>{% block title %} Create a New Post {% endblock %}</h1>

<form method="post">
    <div class="form-group">
        <label for="title">Title</label>
        <input type="text" name="title"
               placeholder="Post title" class="form-control"
               value="{{ request.form['title'] }}"></input>
    </div>

    <div class="form-group">
        <label for="content">Content</label>
        <textarea name="content" placeholder="Post content"
                  class="form-control">{{ request.form['content'] }}</textarea>
    </div>
    <div class="form-group">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</form>
{% endblock %}

La plupart de ce code est du HTML standard. Il affichera une zone de saisie pour le titre du post, une zone de texte pour le contenu du post et un bouton pour soumettre le formulaire.

La valeur du champ du titre de publication est {{ request.form['title'] }} et la zone de texte a la valeur {{ request.form['content'] }}, cela est fait pour que les données que vous saisissez ne soient pas perdues si quelque chose ne va pas. Par exemple, si vous écrivez un long post et que vous oubliez de lui donner un titre, un message s'affichera pour vous informer que le titre est requis. Cela se produira sans perdre le post que vous avez écrit puisque celui-ci sera stocké dans l'objet global request auquel vous avez accès dans vos modèles.

Maintenant, avec le serveur de développement en cours d'exécution, utilisez votre navigateur pour naviguer vers la route /create :

http://127.0.0.1:5000/create

Vous verrez une page Créer un nouveau post avec une boîte pour un titre et du contenu.

Ce formulaire envoie une requête POST à votre fonction de vue create(). Cependant, il n'y a pas encore de code pour gérer une requête POST dans la fonction, donc rien ne se passe après avoir rempli le formulaire et l'avoir soumis.

Vous traiterez la requête POST entrante lorsqu'un formulaire est soumis. Vous ferez cela à l'intérieur de la fonction de vue create(). Vous pouvez traiter séparément la requête POST en vérifiant la valeur de request.method. Lorsque sa valeur est définie sur 'POST', cela signifie que la requête est une requête POST, vous pouvez alors extraire les données soumises, les valider et les insérer dans votre base de données.

Ouvrez le fichier app.py pour l'éditer :

  1. nano app.py

Modifiez la fonction de vue create() pour qu'elle ressemble exactement à ce qui suit :

. . .

@app.route('/create', methods=('GET', 'POST'))
def create():
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        if not title:
            flash('Title is required!')
        else:
            conn = get_db_connection()
            conn.execute('INSERT INTO posts (title, content) VALUES (?, ?)',
                         (title, content))
            conn.commit()
            conn.close()
            return redirect(url_for('index'))

    return render_template('create.html')

Dans l'instruction if, vous vous assurez que le code qui suit n'est exécuté que lorsque la requête est une requête POST via la comparaison request.method == 'POST'.

Vous extrayez ensuite le titre soumis et le contenu de l'objet request.form qui vous donne accès aux données du formulaire dans la requête. Si le titre n'est pas fourni, la condition if not title sera remplie, affichant un message à l'utilisateur lui informant que le titre est requis. Si, en revanche, le titre est fourni, vous ouvrez une connexion avec la fonction get_db_connection() et insérez le titre et le contenu que vous avez reçus dans la table posts.

Vous validez ensuite les modifications dans la base de données et fermez la connexion. Après avoir ajouté le billet de blog à la base de données, vous redirigez le client vers la page d'index en utilisant la fonction redirect(), en lui passant l'URL générée par la fonction url_for() avec la valeur 'index' comme argument.

Enregistrez et fermez le fichier.

Maintenant, naviguez vers la route /create en utilisant votre navigateur web :

http://127.0.0.1:5000/create

Remplissez le formulaire avec un titre de votre choix et un contenu. Une fois que vous avez soumis le formulaire, vous verrez le nouveau post listé sur la page d'index.

Enfin, vous afficherez des messages flash et ajouterez un lien dans la barre de navigation dans le modèle base.html pour avoir un accès facile à cette nouvelle page. Ouvrez le fichier modèle :

  1. nano templates/base.html

Modifiez le fichier en ajoutant une nouvelle balise <li> après le lien À propos à l'intérieur de la balise <nav>. Ensuite, ajoutez une nouvelle boucle for directement au-dessus du bloc content pour afficher les messages flashés en dessous de la barre de navigation. Ces messages sont disponibles dans la fonction spéciale get_flashed_messages() que Flask fournit :

<nav class="navbar navbar-expand-md navbar-light bg-light">
    <a class="navbar-brand" href="{{ url_for('index')}}">FlaskBlog</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
        <li class="nav-item">
            <a class="nav-link" href="#">About</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="{{url_for('create')}}">New Post</a>
        </li>
        </ul>
    </div>
</nav>
<div class="container">
    {% for message in get_flashed_messages() %}
        <div class="alert alert-danger">{{ message }}</div>
    {% endfor %}
    {% block content %} {% endblock %}
</div>

Enregistrez et fermez le fichier. La barre de navigation aura maintenant un élément Nouveau Post qui renvoie à la route /create.

Édition d'un post

Pour qu'un blog soit à jour, vous devrez être en mesure de modifier vos articles existants. Cette section vous guidera dans la création d'une nouvelle page dans votre application pour simplifier le processus de modification d'un article.

Tout d'abord, vous ajouterez une nouvelle route au fichier app.py. Sa fonction de vue recevra l'ID du post à modifier, l'URL sera au format /post_id/edit avec la variable post_id étant l'ID du post. Ouvrez le fichier app.py pour l'éditer :

  1. nano app.py

Ensuite, ajoutez la fonction de vue edit() suivante à la fin du fichier. Modifier un article existant est similaire à en créer un nouveau, donc cette fonction de vue sera similaire à la fonction de vue create() :

. . .

@app.route('/<int:id>/edit', methods=('GET', 'POST'))
def edit(id):
    post = get_post(id)

    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        if not title:
            flash('Title is required!')
        else:
            conn = get_db_connection()
            conn.execute('UPDATE posts SET title = ?, content = ?'
                         ' WHERE id = ?',
                         (title, content, id))
            conn.commit()
            conn.close()
            return redirect(url_for('index'))

    return render_template('edit.html', post=post)

Le message que vous éditez est déterminé par l'URL et Flask passera le numéro d'identification à la fonction edit() via l'argument id. Vous ajoutez cette valeur à la fonction get_post() pour récupérer le message associé à l'ID fourni dans la base de données. Les nouvelles données arriveront dans une requête POST, qui sera gérée à l'intérieur de la condition if request.method == 'POST'.

Tout comme lorsque vous créez un nouveau post, vous extrayez d'abord les données de l'objet request.form, puis vous affichez un message si le titre a une valeur vide, sinon, vous ouvrez une connexion à la base de données. Ensuite, vous mettez à jour la table posts en définissant un nouveau titre et un nouveau contenu où l'ID du post dans la base de données est égal à l'ID qui se trouvait dans l'URL.

Dans le cas d'une requête GET, vous rendez un modèle edit.html en passant la variable post qui contient la valeur retournée par la fonction get_post(). Vous l'utiliserez pour afficher le titre et le contenu existants sur la page d'édition.

Enregistrez et fermez le fichier, puis créez un nouveau modèle edit.html :

  1. nano templates/edit.html

Écrivez le code suivant dans ce nouveau fichier :

{% extends 'base.html' %}

{% block content %}
<h1>{% block title %} Edit "{{ post['title'] }}" {% endblock %}</h1>

<form method="post">
    <div class="form-group">
        <label for="title">Title</label>
        <input type="text" name="title" placeholder="Post title"
               class="form-control"
               value="{{ request.form['title'] or post['title'] }}">
        </input>
    </div>

    <div class="form-group">
        <label for="content">Content</label>
        <textarea name="content" placeholder="Post content"
                  class="form-control">{{ request.form['content'] or post['content'] }}</textarea>
    </div>
    <div class="form-group">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</form>
<hr>
{% endblock %}

Enregistrez et fermez le fichier.

Ce code suit le même schéma sauf pour la syntaxe {{ request.form['title'] ou post['title'] }} et {{ request.form['content'] ou post['content'] }}. Cela affiche les données stockées dans la requête si elles existent, sinon cela affiche les données de la variable post qui a été passée au modèle contenant les données de la base de données actuelle.

Maintenant, rendez-vous à l'URL suivante pour modifier le premier post :

http://127.0.0.1:5000/1/edit

Vous verrez une page Modifier “Premier post”.

Modifiez le message et soumettez le formulaire, puis assurez-vous que le message a été mis à jour.

Vous devez maintenant ajouter un lien qui pointe vers la page de modification de chaque publication sur la page d'index. Ouvrez le fichier modèle index.html:

  1. nano templates/index.html

Modifiez le fichier pour qu'il ressemble exactement à ce qui suit :

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>
    {% for post in posts %}
        <a href="{{ url_for('post', post_id=post['id']) }}">
            <h2>{{ post['title'] }}</h2>
        </a>
        <span class="badge badge-primary">{{ post['created'] }}</span>
        <a href="{{ url_for('edit', id=post['id']) }}">
            <span class="badge badge-warning">Edit</span>
        </a>
        <hr>
    {% endfor %}
{% endblock %}

Enregistrez et fermez le fichier.

Ici, vous ajoutez une balise <a> pour relier à la fonction de vue edit(), en passant la valeur post['id'] pour lier à la page de modification de chaque publication avec le lien Edit.

Supprimer un post

Parfois, un message n'a plus besoin d'être disponible publiquement, c'est pourquoi la fonctionnalité de suppression d'un message est cruciale. Dans cette étape, vous ajouterez la fonctionnalité de suppression à votre application.

Tout d'abord, vous allez ajouter une nouvelle route /ID/delete qui accepte les requêtes POST, similaire à la fonction de vue edit(). Votre nouvelle fonction de vue delete() recevra l'ID du post à supprimer à partir de l'URL. Ouvrez le fichier app.py :

  1. nano app.py

Ajoutez la fonction de vue suivante en bas du fichier :

....

@app.route('/<int:id>/delete', methods=('POST',))
def delete(id):
    post = get_post(id)
    conn = get_db_connection()
    conn.execute('DELETE FROM posts WHERE id = ?', (id,))
    conn.commit()
    conn.close()
    flash('"{}" was successfully deleted!'.format(post['title']))
    return redirect(url_for('index'))

Cette fonction de vue n'accepte que les requêtes POST. Cela signifie que naviguer vers la route /ID/delete dans votre navigateur renverra une erreur car les navigateurs web par défaut envoient des requêtes GET.

Cependant, vous pouvez accéder à cette route via un formulaire qui envoie une requête POST en passant l'ID du post que vous souhaitez supprimer. La fonction recevra la valeur de l'ID et l'utilisera pour récupérer le post de la base de données avec la fonction get_post().

Ensuite, vous ouvrez une connexion à la base de données et exécutez une commande SQL DELETE FROM pour supprimer le post. Vous validez le changement dans la base de données et fermez la connexion tout en affichant un message pour informer l'utilisateur que le post a été supprimé avec succès et en le redirigeant vers la page d'index.

Veuillez noter que vous ne rendez pas un fichier de modèle, cela est dû au fait que vous allez simplement ajouter un bouton Supprimer à la page de modification.

Ouvrez le fichier modèle edit.html :

  1. nano templates/edit.html

Ajoutez ensuite la balise <form> après la balise <hr> et juste avant la ligne {% endblock %} :

<hr>

<form action="{{ url_for('delete', id=post['id']) }}" method="POST">
    <input type="submit" value="Delete Post"
            class="btn btn-danger btn-sm"
            onclick="return confirm('Are you sure you want to delete this post?')">
</form>

{% endblock %}

Vous utilisez la méthode confirm() pour afficher un message de confirmation avant de soumettre la demande.

Maintenant, naviguez à nouveau vers la page de modification d'un article de blog et essayez de le supprimer :

http://127.0.0.1:5000/1/edit

À la fin de cette étape, le code source de votre projet ressemblera au code sur cette page.

Avec cela, les utilisateurs de votre application peuvent désormais rédiger de nouveaux articles de blog, les ajouter à la base de données, modifier et supprimer des articles existants.

Conclusion

Ce tutoriel a introduit les concepts essentiels du framework Python Flask. Vous avez appris à créer une petite application web, à l'exécuter sur un serveur de développement et à permettre à l'utilisateur de fournir des données personnalisées via des paramètres d'URL et des formulaires web. Vous avez également utilisé le moteur de templates Jinja pour réutiliser des fichiers HTML et y inclure de la logique. À la fin de ce tutoriel, vous avez maintenant un blog web entièrement fonctionnel qui interagit avec une base de données SQLite pour créer, afficher, modifier et supprimer des articles de blog en utilisant le langage Python et les requêtes SQL. Si vous souhaitez en savoir plus sur l'utilisation de Flask et SQLite, consultez ce tutoriel sur Comment utiliser les relations de base de données un-à-plusieurs avec Flask et SQLite.

Vous pouvez développer davantage cette application en ajoutant une authentification des utilisateurs afin que seuls les utilisateurs enregistrés puissent créer et modifier des articles de blog. Vous pouvez également ajouter des commentaires et des balises pour chaque article de blog, ainsi que la possibilité de télécharger des fichiers pour permettre aux utilisateurs d'inclure des images dans l'article. Consultez la documentation Flask pour plus d'informations.

Flask a de nombreuses extensions créées par la communauté. Voici une liste d'extensions que vous pourriez envisager d'utiliser pour faciliter votre processus de développement :

  • Flask-Login : gère la session utilisateur et s'occupe de la connexion et de la déconnexion, ainsi que de la mémorisation des utilisateurs connectés.
  • Flask-SQLAlchemy : simplifie l'utilisation de Flask avec SQLAlchemy, un kit d'outils SQL en Python et un Object Relational Mapper pour interagir avec des bases de données SQL.
  • Flask-Mail : aide à la tâche d'envoi de messages électroniques dans votre application Flask.