Outils pour utilisateurs

Outils du site


cours:informatique:dev:python:concevez_site_avec_flask:140_afficher_contenu_template

Notes et transcriptions du cours “Concevez un site avec Flask” disponible sur la plateforme Openclassrooms

Affichez le contenu d'un template

Notre page d'accueil est assez vide, n'est-ce pas ? C'est le moment d'afficher le contenu d'index.html !

Comprenez l'architecture modèle / vue / template

La structure d'un projet est une des clés qui garantit sa bonne évolution, exactement comme dans votre ordinateur ! Imaginez que vous repreniez le projet d'une autre personne, ou que vous ouvriez le vôtre dans six mois. Vous ne voulez pas perdre de temps à chercher comment il est organisé ! Vous voulez aller droit au but et apporter votre modification sans pour autant tout casser.

C'est pourquoi la plupart des frameworks pensés pour le web choisissent de séparer les fichiers dans plusieurs dossiers distincts. Cela peut paraître un peu contraignant au début mais ce sont de bonnes pratiques qui garantissent la bonne évolution de votre projet.

Flask, comme vous le savez désormais, n'impose pas vraiment de structure, il la propose. S'inspirant du modèle MVC (Modèle / Vue / Contrôleur) de bien des frameworks, il se base sur trois piliers fortement imbriqués : le modèle, la vue et le template abrégé MVT. Voyons-les en détail.

Le modèle

Un modèle, comme nous l'avons vu dans le chapitre précédent, définit la structure de l'objet qui sera stocké dans la base de données : c'est la représentation, la structure de l'information utile.

Dans Flask, le modèle de chaque objet est représenté par une classe dans le fichier models.py. La classe hérite de db.Model et peut donc utiliser les méthodes de la classe parent.

Deux parties sont à distinguer dans un modèle :

  • la structure de l'item dans la base de données ;
  • les attributs d'instance exposés.

L'appel à db.Column crée une nouvelle colonne dans la table. Cela permet de filtrer les résultats d'une recherche par le contenu de cette colonne, par exemple, en utilisant la méthode TableName.query.filter_by(column_name=filter).first().

La méthode __init__, elle, construit l'instance. Chaque attribut exposé à cet endroit pourra être modifié par la suite de la même manière que n'importe quelle instance de classe Python. Dans notre exemple, vous pouvez ainsi créer un nouvel objet content dans la base en spécifiant sa description et son genre mais pas son id.

Exemple d'un modèle

Dans notre projet, models.py contient un modèle Content. Pour comprendre la différence entre ce qui est stocké en base et les valeurs retournées, je vous propose d'améliorer la gestion de l'attribut gender.

Pour l'instant, nous enregistrons le genre en tant qu'entier mais nous ne connaissons pas (encore) le chiffre associé à chacun.

Nous verrons plus tard que Facebook renvoie les valeurs male ou female de l'utilisateur connecté. Il serait donc intéressant de pouvoir associer chaque chaîne de caractères à un nombre.

Créons une nouvelle classe dans le fichier models.py, Gender, qui héritera de enum :

models.py
from flask_sqlalchemy import SQLAlchemy
 
from .views import app
import logging as lg
 
import enum
 
 
class Gender(enum.Enum):
    female = 0
    male = 1
    other = 2
 
 
# Create database connection object
db = SQLAlchemy(app)
 
 
class Content(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.String(200), nullable=False)
    gender = db.Column(db.Enum(Gender), nullable=False)
 
    def __init__(self, description, gender):
        self.description = description
        self.gender = gender
 
 
def init_db():
    db.drop_all()
    db.create_all()
    db.session.add( Content( gender=Gender['male'], description="Le renard et la tortue" ) )
    db.session.add( Content( gender=Gender['female'], description="Le lièvre et le corbeau" ) )
    db.session.commit()
    lg.root.setLevel(lg.INFO)
    lg.info("Database initialized.")
Nous avons utilisé un énumérable pour gérer le genre. Pour en savoir plus, lisez la documentation du type enum en Python.

Cela vous permet de créer des instances de cette manière :

Content('Personne ne te faisait pitié, ni sur le moment, ni après, on était absolument sans défense devant toi.', Gender['male'])

Vous pourrez ensuite les retrouver de la manière suivante :

Content.query.filter_by(gender=Gender['male'])

Le template

Un template est un fichier HTML qui peut recevoir des objets Python et qui est lié à une vue (nous y reviendrons). Il est placé dans le dossier templates.

Concrètement, un template peut interpréter des variables et les afficher. Par exemple, nous pouvons “donner” la variable username=“Tom” au template index.html et ce dernier l'affichera à la place du prénom.

Le template n'a accès qu'aux variables que la vue lui transmet, et pas aux autres. Par exemple, le template n'a pas accès à la variable db.

La vue

Les vues contenues dans le fichier views.py jouent un rôle primordial : elles décident du contenu à afficher sur une page. Plus spécifiquement, ce sont elles qui génèrent le contenu à renvoyer aux requêtes qui leur sont adressées.

Une vue est une fonction qui renvoie une réponse à une requête HTTP. Toute fonction décorée par @app.route est une vue.

On appelle route l'URL à laquelle va répondre la vue. Par exemple : /index.

Afin de bien comprendre le rôle majeur des vues, intéressons-nous au cheminement d'une requête.

GET/HTTP/1.1
Host:le-test-ultime.hello-birds.com
  • Le serveur à l'adresse le-test-ultime.hello-birds.com reçoit la requête HTTP. Il cherche dans les vues la route correspondant à la requête en fonction de la méthode HTTP utilisée et de l'URL.
  • Le serveur exécute la vue : éventuellement, si la route contient des paramètres, ils sont passés comme arguments à la vue. Si une modification d'un objet en base de données est demandée, la vue fait appel au modèle. Si un template est demandé, la vue l'appelle.
  • Le serveur transmet la réponse HTTP de la vue au navigateur de l'utilisateur (appelé communément client).
Le protocole HTTP est très intéressant ! Tout le web que nous connaissons l'utilise. Afin d'aller plus loin, je vous invite fortement à lire la partie Une architecture basée sur un protocole que l'on connaît bien : HTTP du cours de Sarah Khalil.

Exemple de vue

Afin de mettre en pratique ce que nous venons d'explorer, affichons le contenu du template index.html lorsque l'utilisateur arrive sur la page d'accueil. Pour cela, modifions le fichier views.py.

views.py
  1. from flask import Flask, render_template
  2.  
  3. app = Flask(__name__)
  4.  
  5. # Config options - Make sure you created a 'config.py' file.
  6. # To get one variable, tape app.config['MY_VARIABLE']
  7. app.config.from_object('config')
  8.  
  9. @app.route('/')
  10. def index():
  11. return render_template('index.html')
Vous pouvez associer une vue à plusieurs URL ! Il vous suffit de les indiquer les unes à la suite des autres à l'aide du décorateur @app.route:

Pourquoi ajouter un slash à la fin de l'URL ?

Les utilisateurs peuvent taper deux adresses différentes /index ou /index/. Ce ne sont pas les mêmes ! Si vous déclarez une route sans le slash final (/index), le serveur renverra une erreur 404 (page non trouvée) si l'utilisateur tape /index/. Mais si vous déclarez une route avec le slash final (/index/) et que l'utilisateur tape /index, le serveur ne renverra pas d'erreur. Pensez-y !

Le nom de vos routes doit être parlant ! Vous et l'utilisateur devez être en mesure de comprendre, en lisant l'URL, l'action qui sera effectuée. Par exemple, évitez d'utiliser une route qui aurait cette structure : /mise_a_jour_description_1. Préférez l'url suivante : /contents/1/update.

Il s'agit d'ailleurs d'une des bonnes pratiques les plus importantes à respecter lorsque l'on crée une application web : l'interface uniforme de l'architecture REST.

Appliquez REST : les dénominations conseillées des routes

REST est un acronyme pour REpresentational State Transfer. Cette architecture impose six contraintes que vous pouvez choisir de respecter :

  • Séparation client / serveur
  • Stateless (sans état)
  • Cacheable (cachable)
  • Layered system (système à plusieurs couches)
  • Uniform interface (interface uniforme)
  • Code on demand

Comment appliquer REST dans un projet Flask ? La question demanderait un cours entier ! Intéressez-vous en premier à l'interface uniforme et prenez le temps de bien comprendre comment créer de bonnes URL.

Prenez le temps de lire le chapitre Une architecture, pas un protocole du cours Construisez une API REST avec Symphony de Sarah Khalil.

Récupérer le code du chapitre

:TODO_DOCUPDATE:

En résumé

  • Un projet Flask se structure à partir de trois piliers : le modèle, la vue et le template ;
  • Un modèle représente la structure d’un objet de la base de données ;
  • Un template est un fichier HTML dans lequel on peut récupérer des objets Python ;
  • Une vue a la responsabilité de traiter le contenu à envoyer à l’URL indiquée par la route ;
  • Une route dans Flask se crée en utilisant le décorateur @app.route.

Maintenant que votre application web est accessible depuis la route créée et affiche le template et le modèle, vérifions que vous avez compris les notions de Flask avec un quiz. Vous verrez ensuite comment organiser votre projet en templates.

◁ Précédent | ⌂ Retour au sommaire | Suivant ▷

cours/informatique/dev/python/concevez_site_avec_flask/140_afficher_contenu_template.txt · Dernière modification : 2023/10/11 19:13 de yoann