Implémenter la création d'un article
Maintenant que vous avez fini d'afficher les articles de blog, vous devez permettre aux utilisateurs de notre application Web d'écrire de nouveaux articles de blog et de les ajouter à la base de données, de modifier les articles existants et de supprimer les articles de blog inutiles.
Avant d'entamer la réalisation de cette nouvelle tâche, veuillez penser à :
- déplacer l'intitulé de la tâche dans la colonne « In progress »\
- créer une nouvelle branche dans Git :
git checkout -b update-one-post
Création d'un nouvel article
À ce stade, vous disposez d'une application qui affiche les articles mais qui ne vous permet pas encore d'en ajouter, sauf si vous vous connectez directement à la base de données MySQL/MariaDB et que vous en ajoutez un manuellement. Dans cette section, nous allons créer une page sur laquelle vous pourrez créer un article en fournissant son titre et son contenu.
Ouvrez le fichier app.py
pour le modifier et importer ce qui suit
depuis le framework Flask :
- L'objet
request
global pour accéder aux données de la requête entrante qui sera soumise via un formulaire HTML. - La fonction
url_for()
pour générer des URL. - La fonction
flash()
pour afficher un message lorsqu'une requête est traitée. - La fonction
redirect()
pour rediriger le client vers un autre emplacement.
Ajoutez les importations à notre fichier comme suit :
import mysql.connector
from flask import Flask, render_template, request, url_for, flash,
redirect
from werkzeug.exceptions import abort
from post import Post
. . .
La fonction flash()
stocke les messages flashs dans la session du
navigateur du client, ce qui nécessite la définition d'une clé secrète.
Cette clé secrète est utilisée pour sécuriser les sessions, ce qui
permet à Flask de se souvenir des informations d'une requête à l'autre,
comme passer de la page du nouveau message à la page d'index.
L'utilisateur peut accéder aux informations stockées dans la session,
mais ne peut pas les modifier s'il ne dispose pas de la clé secrète, de
sorte que vous ne devez jamais autoriser quiconque à accéder à notre clé
secrète.
Pour plus d'informations, consultez la documentation Flask pour les sessions, à l'adresse :
https://flask-fr.readthedocs.io/api/#sessions
Pour définir une clé secrète, vous ajouterez une configuration
SECRET_KEY
via l'objet app.config
, dans notre fichier
python-flask-blog/app.py
:
Ajoutez-la directement après la définition de l'app
avant de définir
la fonction de visualisation index()
. . .
app = Flask(__name__)
app.config['SECRET_KEY'] = 'Coller ici la clé secrète'
\@app.route('/')
def index():
conn = get_db_connection()
posts = conn.execute('SELECT \* FROM posts').fetchall()
conn.close()
return render_template('index.html', posts=posts)
. . .
Cependant la clé secrète doit être une longue chaîne aléatoire. De plus nous aurons besoin de mémoriser la date et l'heure de création de l'article. Donc, nous pouvons améliorer le code de notre application Web en insérant la ligne suivante dans la liste des importations de bibliothèques :
import secrets, datetime
et remplacer la ligne :
app.config['SECRET_KEY'] = 'Coller ici la clé secrète'
par :
app.config['SECRET_KEY'] = secrets.token_hex(16)
Après avoir défini une clé secrète, nous allons créer une fonction de
visualisation qui rendra un modèle affichant un formulaire que vous
pouvez remplir pour créer un nouveau article de blog.
Ajoutez cette nouvelle fonction au bas du fichier `app.py `:
. . .
\@app.route('/create', methods=('GET', 'POST'))
def create():
return render_template('create.html')
Cela crée une route /create
qui accepte les demandes 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
des formulaires, vous passerez 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, créez un fichier appelé
create.html
dans notre dossier templates
:
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 majorité de ce code est du HTML standard. Il affichera une zone de saisie pour le titre du message, une zone de texte pour le contenu du message et un bouton pour soumettre le formulaire.
La valeur du titre de l'article est {{ request.form['title'] }}
et la zone de texte a la valeur {{ request.form['content'] }}
,
ceci afin que les données que vous entrez ne soient pas perdues si
quelque chose se passe mal. Par exemple, si vous écrivez un long article
et que vous oubliez de lui donner un titre, un message s'affiche pour
vous informer que le titre est requis. Cela se produira sans perdre le
message que vous avez écrit puisqu'il sera stocké dans l'objet
request
global auquel vous avez accès dans vos modèles.
Enregistrez et fermez le fichier,
puis stoppez le serveur Web (Ctrl + C
) et redémarrez le : flask run
Vous pouvez tester notre page dans votre navigateur.
Maintenant que le serveur de développement tourne, utilisez notre
navigateur pour accéder à la route /create
:
Vous verrez une page Create a New Post
avec une boîte pour un titre
et un contenu.
N'oubliez pas, la pratique est la clé
pour maîtriser une nouvelle compétence. Donc, si vous n'avez pas réussi du premier coup, ne vous découragez pas et essayez à nouveau.
Ce formulaire soumet une demande POST à notre fonction create()
view. Cependant, il n'y a pas encore de code pour traiter une demande
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 sera
soumis. Nous ferons cela à l'intérieur de la fonction de visualisation
create()
. Vous pouvez traiter la demande POST sépar ément en
vérifiant la valeur de request.method
. Lorsque sa valeur est réglée
sur 'POST'
, elle signifie que la requête est une requête POST,
nous allons ensuite continuer à extraire les données soumises, le
valider et l'insérer dans notre base de données.
Ouvrez le fichier app.py
pour le modifier :
Modifiez la fonction de visualisation 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:
myconn = get_db_connection()
mycursor = myconn.cursor(dictionary=True)
mycursor.execute('INSERT INTO post (created, title, content) VALUES (%s, %s, %s)', (datetime.datetime.now(), title, content))
myconn.commit()
myconn.close()
return redirect(url_for('index'))
return render_template('create.html')
Dans la déclaration if
, vous devez vous assurer que le code qui suit
n'est exécuté que lorsque la demande est une demande POST via la
comparaison
request.method == 'POST'
.
Vous extrayez ensuite le titre et le contenu soumis de l'objet
request.form
qui vous donne accès aux données du formulaire dans la
demande. Si le titre n'est pas fourni, la condition if not title
serait remplie, en affichant un message à l'utilisateur l'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çu dans la table post
.
Vous validez ensuite les modifications dans la base de données et coupez
la connexion. Après avoir ajouté l'article 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'
en argument.
Enregistrez et fermez le fichier, puis naviguez vers la route
/create
en utilisant notre navigateur Web :
http://127.0.0.1:5000/create
Remplissez le formulaire avec un titre de notre choix et un peu de contenu.
Une fois que vous avez soumis le formulaire, vous verrez le nouveau article listé sur la page d'index.
Enfin, vous afficherez des messages et ajouterez un lien vers la barre
de navigation dans le modèle base.html
pour accéder facilement à
cette nouvelle page.
Ouvrez le fichier modèle templates/base.html
et modifiez le en
ajoutant une nouvelle balise <li>
à la suite du lien "About"
à
l'intérieur de la balise <nav>
. Ensuite, ajoutez un nouveau for loop
directement au-dessus du bloc content
pour afficher les
messages sous la barre de navigation. Ces messages sont disponibles dans
la fonction spéciale get_flashed_messages()
que Flask fournit :
. . .
</nav>
<li class="nav-item">
<a class="nav-link" href="{{url_for('create')}}">
New Post
</a>
</li>
. . .
<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 comportera
désormais un élément New Post
qui renvoie à la route /create
.