Lister des enregistrements¶
Objectif : lire plusieurs lignes en base et les afficher dans une vue.
Ce que vous allez apprendre : au palier débutant Première base SQL, vous
avez lu une ligne avec fetch_one. Ici vous lisez toute la table avec
core.database.db.fetch_all, qui retourne une liste de dictionnaires, puis
vous l'itérez dans la vue avec une boucle Jinja {% for %}.
Premier palier du niveau intermédiaire de la progression officielle des starters, après Écrire en base (dernier palier du niveau débutant).
Ce que ce starter montre¶
- une route
GET /list-recordsqui lit plusieurs lignes ; core.database.db.fetch_all(liste de lignes) au lieu defetch_one;- une vue HTML qui boucle sur les lignes avec
{% for m in messages %}.
Aucune écriture en base. Aucun formulaire. Aucun CRUD complet. Aucune entité JSON.
Classes Forge utilisées¶
| Classe | Rôle dans ce starter | Référence |
|---|---|---|
Request |
Reçue par la méthode du contrôleur. | Request |
Response |
Produite ici via render(...). |
Response |
BaseController |
Fournit render(...) pour la vue. |
BaseController |
core.database.db.fetch_all |
Lit plusieurs lignes (liste de dicts). | Migrations SQL |
Tester¶
La table neutre first_sql_messages est créée et peuplée par la migration
livrée avec ce starter :
Ouvrez https://localhost:8000/list-records → la liste des messages s'affiche.
Les routes¶
# mvc/routes.py
from mvc.controllers.list_records_controller import ListRecordsController
with router.group("", public=True) as pub:
pub.add("GET", "/list-records", ListRecordsController.index, name="list_records_index")
Le contrôleur¶
# mvc/controllers/list_records_controller.py
from core.database.db import fetch_all
from core.http.request import Request
from core.http.response import Response
from core.mvc.controller.base_controller import BaseController
SELECT_ALL_MESSAGES = "SELECT id, content FROM first_sql_messages ORDER BY id"
class ListRecordsController(BaseController):
@staticmethod
def index(request: Request) -> Response:
messages = fetch_all(SELECT_ALL_MESSAGES)
return BaseController.render(
"list_records/index.html",
context={"messages": messages},
request=request,
)
Comprendre ce code¶
fetch_all(SELECT_ALL_MESSAGES)exécute leSELECTet retourne une liste de dictionnaires (une entrée par ligne), là oùfetch_onene renvoyait qu'un seul dictionnaire (ouNone).- Le SQL reste une constante de module lisible et paramétrable (principe « SQL visible »).
- La liste est passée à la vue dans le contexte (
{"messages": messages}).
La vue¶
<!-- mvc/views/list_records/index.html -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Lister des enregistrements — Forge</title>
</head>
<body>
<h1>Messages</h1>
{% if messages %}
<ul>
{% for m in messages %}
<li>#{{ m.id }} — {{ m.content }}</li>
{% endfor %}
</ul>
{% else %}
<p>Aucun message en base.</p>
{% endif %}
</body>
</html>
Comprendre ce code¶
{% for m in messages %}itère la liste reçue du contrôleur ; chaquemest un dictionnaire dont on litm.idetm.content.{% if messages %}gère proprement le cas d'une table vide.- Pas encore de gabarit partagé (
{% extends %}) : c'est le palier Héritage de gabarit qui l'introduira ; ici la page reste un document HTML complet.
À retenir¶
fetch_allrenvoie une liste ;fetch_onerenvoie une ligne.- Une vue affiche une collection avec
{% for %}; pensez au cas vide. - Le SQL reste visible et paramétré, jamais concaténé.
Après ce starter¶
Passez au palier suivant : Rechercher / filtrer une liste — filtrer la liste selon un mot-clé saisi par l'utilisateur.