Fonctions de vue — afficher la liste des articles et les pages de détail
Dans ce chapitre, vous apprendrez à interroger des données depuis la base de données à l'aide de fonctions de vue, à afficher la page d'accueil et les pages de détail, et à diviser les routes à l'aide de Blueprint.
Les responsabilités des fonctions de vue
Les fonctions de vue Flask ont les mêmes responsabilités que Django :Recevoir la requête → Interroger les données → Rendre le template。
Exemple
from flask import Flask, render_template
from models import Post, Category
@app.route("/")
def index():
"""Page d'accueil du blog : affiche tous les articles"""
posts = Post.query.order_by(Post.created_at.desc()).all()
categories = Category.query.all()
return render_template('index.html', posts=posts, categories=categories)
Paramètres de chemin et paramètres de requête
| Type de paramètre | Exemple d'URL | Comment les vues sont obtenues |
|---|---|---|
| Paramètre de chemin | /post/3 | Dans les routes, <type:variable_name> → paramètre de fonction |
| Paramètre de requête | /?category=python | request.args.get('key') |
Les routes Flask prennent en charge plusieurs convertisseurs de type :<int:id>(integer),<string:slug>(par défaut, n'inclut pas /),<path:path>(contient /),<float:price>etc.
Page de détail de l'article
Exemple
from flask import abort
@app.route("/post/<int:post_id>")
def post_detail(post_id):
"""Page de détail de l'article"""
# get_or_404 est équivalent à : Post.query.get(post_id) or abort(404)
post = Post.query.get_or_404(post_id,
description=f'L'article #{post_id} n'existe pas')
return render_template('post_detail.html', post=post)
Page d'erreur 404 personnalisée
Exemple
def not_found(error):
return render_template('404.html'), 404
Filtrage par catégorie
Exemple
from flask import request
@app.route("/")
def index():
category_slug = request.args.get('category', '')
keyword = request.args.get('q', '') # Recherche par mot-clé (implémentée au chapitre 6)
posts_query = Post.query.order_by(Post.created_at.desc())
# Filtrer par catégorie
if category_slug:
posts_query = posts_query.join(Category).filter(Category.slug == category_slug)
posts = posts_query.all()
categories = Category.query.all()
return render_template('index.html',
posts=posts, categories=categories,
category_slug=category_slug, keyword=keyword)
request.argsest un MultiDict immuable, utilisé pour lire les paramètres de requête d'URL. Utilisez.get('key', '默认值')Récupération sécurisée, renvoie une valeur par défaut lorsque le paramètre n'existe pas au lieu de lever une erreur.
Blueprint — découpage des routes
Lorsque les fonctions de vue se multiplient, les empiler toutes dans app.py devient ingérable.
BlueprintC'est le mécanisme de regroupement de routes de Flask : répartir les vues par modules fonctionnels et les enregistrer via app.register_blueprint().
app/ ├── blueprints/ │ ├── __init__.py │ ├── main.py # 首页、关于、搜索 │ └── posts.py # 文章列表、详情 ├── templates/ ├── models.py └── __init__.py
Exemple
from flask import Blueprint, render_template, request
from app.models import Post, Category
# Blueprint('blueprint_name', __name__, url_prefix='/')
main_bp = Blueprint('main', __name__)
@main_bp.route("/")
def index():
"""Page d'accueil du blog"""
category_slug = request.args.get('category', '')
posts_query = Post.query.order_by(Post.created_at.desc())
if category_slug:
posts_query = posts_query.join(Category).filter(Category.slug == category_slug)
return render_template('index.html',
posts=posts_query.all(),
categories=Category.query.all(),
category_slug=category_slug)
Exemple
from flask import Blueprint, render_template, abort
from app.models import Post
posts_bp = Blueprint('posts', __name__)
@posts_bp.route("/post/<int:post_id>")
def post_detail(post_id):
post = Post.query.get_or_404(post_id)
return render_template('post_detail.html', post=post)
Enregistrez le Blueprint au point d'entrée de l'application :
Exemple
from flask import Flask
from app.blueprints.main import main_bp
from app.blueprints.posts import posts_bp
app = Flask(__name__)
# Enregistrer les blueprints : toutes les fonctions de vue des blueprints seront fusionnées dans la même application
app.register_blueprint(main_bp)
app.register_blueprint(posts_bp)
Un Blueprint peut spécifier
url_prefix(tel queurl_prefix='/blog'), puis toutes les routes à l'intérieur du blueprint auront automatiquement ce préfixe ajouté. Un Blueprint peut aussi avoir ses propres répertoires de modèles et de fichiers statiques.
Création des modèles pour la page d'accueil et la page de détail
index.html
Exemple
{% extends 'base.html' %}
{% block title %}EXAMPLE Blog - Accueil{% endblock %}
{% block content %}
<h2 class="section-title">Derniers articles</h2>
<!-- Navigation de filtrage par catégorie -->
<div class="category-bar">
<a href="{{ url_for('main.index') }}"
class="{% if not category_slug %}active{% endif %}">Toutes</a>
{% for cat in categories %}
<a href="{{ url_for('main.index', category=cat.slug) }}"
class="{% if category_slug == cat.slug %}active{% endif %}">
{{ cat.name }}
</a>
{% endfor %}
</div>
{% if posts %}
<div class="article-grid">
{% for post in posts %}
<a href="{{ url_for('posts.post_detail', post_id=post.id) }}" class="card-link">
<div class="article-card">
<div class="card-content">
<span class="card-category">{{ post.category.name }}</span>
<h3>{{ post.title }}</h3>
<p>{{ post.summary|truncate(80) }}</p>
<span class="card-date">{{ post.created_at.strftime('%Y-%m-%d') }}</span>
</div>
</div>
</a>
{% endfor %}
</div>
{% else %}
<p class="empty-tip">Pas encore d'articles dans cette catégorie.</p>
{% endif %}
{% endblock %}
Lors de l'utilisation d'une vue Blueprint dans url_for(), le format est
url_for('蓝图名.函数名'), tel queurl_for('posts.post_detail', post_id=3). Notez la différence avec celle de Django{% url %}comparaison de balises : Flask utilise{{ url_for() }}, peut être imbriqué dans des expressions Python pour plus de flexibilité.
Résumé du chapitre
Dans ce chapitre, vous avez maîtrisé les vues Flask et l'organisation des routes : Post.query pour interroger les données, paramètre de chemin <int:post_id> et paramètre de requête request.args, get_or_404 pour des requêtes sûres, abort(404) et pages d'erreur personnalisées, et Blueprint pour répartir les routes par module.
Le blog dispose désormais de trois pages complètes : la liste d'articles de la page d'accueil, le filtrage par catégorie et les pages de détail.
autres extensions