Supprimer un enregistrement¶
Objectif : supprimer une ligne via une action destructive sécurisée.
Ce que vous allez apprendre : la dernière opération du CRUD — supprimer.
Une suppression ne se fait jamais par un simple lien GET : elle passe par
un POST protégé par CSRF et core.database.db.execute("DELETE … WHERE id =
?").
Palier 6 du niveau intermédiaire de la progression officielle des starters, après Modifier un enregistrement.
Ce que ce starter montre¶
- une liste avec un bouton supprimer par ligne (mini-formulaire
POST) ; - le jeton CSRF sur chaque formulaire de suppression ;
execute("DELETE … WHERE id = ?")paramétré ;- après écriture, on relit et on ré-affiche la liste à jour.
Classes Forge utilisées¶
| Classe | Rôle dans ce starter | Référence |
|---|---|---|
Request |
request.route_param("id"). |
Request |
Response |
Produite via render(...). |
Response |
BaseController |
render(...) + csrf_token(...). |
BaseController |
core.database.db.execute / fetch_all |
Supprimer une ligne, relire la liste. | Migrations SQL |
Tester¶
Ouvrez https://localhost:8000/delete-record, cliquez supprimer sur une
ligne → elle disparaît de la liste.
Le contrôleur¶
# mvc/controllers/delete_record_controller.py
SELECT_ALL = "SELECT id, content FROM first_sql_messages ORDER BY id"
DELETE_ONE = "DELETE FROM first_sql_messages WHERE id = ?"
class DeleteRecordController(BaseController):
@staticmethod
def index(request: Request) -> Response:
messages = fetch_all(SELECT_ALL)
return BaseController.render(
"delete_record/index.html",
context={"messages": messages, "csrf_token": BaseController.csrf_token(request)},
request=request,
)
@staticmethod
def delete(request: Request) -> Response:
record_id = int(request.route_param("id"))
execute(DELETE_ONE, (record_id,))
messages = fetch_all(SELECT_ALL)
return BaseController.render(
"delete_record/index.html",
context={"messages": messages, "csrf_token": BaseController.csrf_token(request),
"deleted": True},
request=request,
)
Comprendre ce code¶
- La suppression est un POST : une action qui modifie l'état n'est jamais
un
GET(un lien ou un robot ne doivent pas pouvoir supprimer). execute(DELETE_ONE, (record_id,))— l'idest un paramètre lié.- Après l'écriture, on relit (
fetch_all) et on ré-affiche la liste.
La vue¶
<!-- mvc/views/delete_record/index.html -->
{% for m in messages %}
<li>
#{{ m.id }} — {{ m.content }}
<form method="post" action="/delete-record/{{ m.id }}" style="display:inline">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<button type="submit">supprimer</button>
</form>
</li>
{% endfor %}
Comprendre ce code¶
- Chaque ligne porte son propre mini-formulaire
POSTvers/delete-record/{id}avec le jeton CSRF. - Pas de lien
GETde suppression : on protège l'action destructive.
À retenir¶
- Supprimer =
POST+ CSRF +DELETE … WHERE id = ?paramétré. - Une action qui change l'état n'est jamais un
GET. - Après l'écriture, on relit la base pour ré-afficher l'état réel.
Après ce starter¶
Passez au palier suivant : Mémoriser un état en session — garder un état côté serveur entre les requêtes.