#路由(Routing)艺术:变量规则、HTTP 方法与唯一 URL
📂 所属阶段:第一阶段 — 破冰启航(基础篇)
🔗 相关章节:初识 Flask · Jinja2 模板引擎
#1. 路由基础
#1.1 定义路由
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def index():
return "<h1>欢迎来到道满博客!</h1>"
@app.route("/about")
def about():
return "<p>关于道满</p>"
if __name__ == "__main__":
app.run(debug=True)#1.2 路由装饰器原理
# 装饰器等价于:
def index():
return "<h1>欢迎!</h1>"
index = app.route("/")(index)#2. 路径变量(动态路由)
#2.1 基本用法
@app.route("/user/<username>")
def show_user(username):
return f"<h1>用户:{username}</h1>"
@app.route("/post/<int:post_id>")
def show_post(post_id):
return f"<h1>文章ID:{post_id}</h1>"
@app.route("/article/<path:subpath>")
def show_article(subpath):
return f"文章路径:{subpath}"#2.2 变量类型
| 转换器 | 说明 | 示例 |
|---|---|---|
string | 默认,不含斜杠的字符串 | /user/john |
int | 整数 | /post/42 |
float | 浮点数 | /rate/3.14 |
path | 含斜杠的路径 | /file/path/to/doc |
uuid | UUID 格式 | /item/550e8400-e29b-41d4-a716-446655440000 |
any | 指定多个值 | /item/<any(a,b):action> |
@app.route("/item/<any(edit,delete,view):action>")
def item_action(action):
return f"执行操作:{action}"
# 访问 /item/edit → action="edit"
# 访问 /item/delete → action="delete"#2.3 多个路径变量
@app.route("/blog/<int:year>/<int:month>/<slug>")
def blog_archive(year, month, slug):
from datetime import datetime
date = datetime(year, month, 1)
return f"<h1>{date.strftime('%Y年%m月')}</h1><p>{slug}</p>"
# 访问 /blog/2026/3/getting-started
# → year=2026, month=3, slug="getting-started"#3. HTTP 方法
#3.1 基础方法
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
# 处理登录逻辑
return redirect(url_for("dashboard"))
return render_template("login.html")#3.2 RESTful HTTP 方法
@app.route("/articles/<int:article_id>", methods=["GET"])
def get_article(article_id):
"""获取文章"""
article = Article.query.get_or_404(article_id)
return render_template("article.html", article=article)
@app.route("/articles", methods=["POST"])
def create_article():
"""创建文章"""
# 从 request.form 获取数据
title = request.form.get("title")
content = request.form.get("content")
new_article = Article(title=title, content=content)
db.session.add(new_article)
db.session.commit()
return redirect(url_for("article", article_id=new_article.id))
@app.route("/articles/<int:article_id>/edit", methods=["GET", "POST"])
def edit_article(article_id):
"""编辑文章"""
article = Article.query.get_or_404(article_id)
if request.method == "POST":
article.title = request.form.get("title")
db.session.commit()
flash("文章已更新!")
return redirect(url_for("article", article_id=article.id))
return render_template("edit_article.html", article=article)
@app.route("/articles/<int:article_id>/delete", methods=["POST"])
def delete_article(article_id):
"""删除文章(禁止 GET)"""
article = Article.query.get_or_404(article_id)
db.session.delete(article)
db.session.commit()
flash("文章已删除。")
return redirect(url_for("index"))#4. URL 反向生成
#4.1 url_for 函数
from flask import url_for, redirect
@app.route("/")
def index():
return "首页"
@app.route("/user/<name>")
def user_profile(name):
return f"用户:{name}"
@app.route("/articles")
def article_list():
return "文章列表"
# 在模板中使用:
# {{ url_for('index') }} → /
# {{ url_for('user_profile', name='alice') }} → /user/alice
# {{ url_for('article_list') }} → /articles
# 在代码中使用:
@app.route("/goto")
def goto():
return redirect(url_for("article_list"))#4.2 url_for 的优势
# ❌ 硬编码 URL:改路由时要改所有引用
"<a href='/user/alice'>Alice</a>"
redirect("/user/alice")
# ✅ url_for:改路由后自动更新
"<a href='{{ url_for('user_profile', name='alice') }}'>Alice</a>"
redirect(url_for("user_profile", name="alice"))#5. 唯一 URL / 尾部斜杠
#5.1 Flask 的智能重定向
@app.route("/about")
def about():
return "关于页面"
# 访问 /about/ → Flask 自动重定向到 /about
# 访问 /about → 返回 "关于页面"#5.2 强制无尾部斜杠
@app.route("/contact", redirect_to=None) # 默认行为:允许重定向
# 或者明确不允许尾部斜杠
@app.route("/items")
def items():
# 访问 /items/ 会 404
return "物品列表"#6. 路由蓝图模块化
# app/routes/main.py
from flask import Blueprint
main_bp = Blueprint("main", __name__)
@main_bp.route("/")
def index():
return render_template("index.html")
@main_bp.route("/about")
def about():
return render_template("about.html")
# app/__init__.py
from app.routes.main import main_bp
app.register_blueprint(main_bp)#7. 小结
# 路由速查
# 基本路由
@app.route("/path")
def handler():
...
# 变量路由
@app.route("/user/<name>")
@app.route("/post/<int:post_id>")
# 多方法
@app.route("/login", methods=["GET", "POST"])
# 反向生成
url_for("handler_name", arg=value)
# 蓝图
bp = Blueprint("name", __name__)
app.register_blueprint(bp, url_prefix="/prefix")💡 设计原则:URL 应该描述资源而非操作。好 URL:
/articles/42/edit→GET /articles/42+PUT /articles/42。
🔗 扩展阅读

