Aller au contenu principal

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 à :

  1. déplacer l'intitulé de la tâche dans la colonne « In progress »\
  2. 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 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 :

http://127.0.0.1:5000/create

Vous verrez une page Create a New Post avec une boîte pour un titre et un contenu.

astuce

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.