Flask是Python生态里极简的Web框架,它把Web开发拆成了最基础的几个概念:请求、路由、响应。相比重量级框架,Flask不强制你使用特定目录结构或ORM,开发者可以用最直白的方式写出第一个能跑起来的网页服务。这种低门槛特性让它成为学习Web后端逻辑的理想起点。

一、环境准备与最小应用
开始之前需要安装Python 3.8以上版本,并用pip创建隔离的虚拟环境。虚拟环境能避免不同项目的依赖互相污染,是专业开发的基本习惯。在终端中执行几条命令即可完成基础配置。
最小Flask应用只需要导入Flask类、创建实例、写一个简单的视图函数。下面这段代码展示了最核心的写法,运行后访问本地5000端口就能看到返回的文本。
# 引入Flask类
from flask import Flask
# 创建应用实例,__name__用于确定资源查找路径
app = Flask(__name__)
# 使用路由装饰器绑定URL和处理函数
@app.route('/')
def hello():
# 返回字符串,Flask会自动包装成响应对象
return 'Hello, Flask!'
# 入口启动代码
if __name__ == '__main__':
app.run(debug=True)
上面的app.run(debug=True)开启了调试模式,代码改动后服务会自动重启,方便排查错误。但要注意调试模式绝不能用于生产环境,因为它会暴露交互式错误页面,存在安全风险。
二、路由与动态参数
路由是Web框架的命脉,它决定了用户访问不同网址时由哪个函数处理。Flask通过@app.route装饰器实现这种映射,并且支持在路径中嵌入变量,让一个函数处理一类请求。
动态参数用尖括号包裹,比如<username>会捕获对应位置的字符串并传给函数。你还可以指定类型转换器,如<int:id>只接受整数,否则返回404。下面示例演示了带参数的路由写法。
from flask import Flask
app = Flask(__name__)
# 静态路由
@app.route('/about')
def about():
return '关于页面'
# 动态路由,捕获用户名
@app.route('/user/<username>')
def show_user(username):
return f'用户:{username}'
# 限定整数类型
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'文章编号:{post_id}'
if __name__ == '__main__':
app.run()
当访问/user/tom时,show_user收到的username就是字符串tom。这种机制避免了写大量重复的判断逻辑,也让URL设计更整洁。如果路径匹配失败,Flask默认返回404状态码,前端可以据此展示NotFound页面。
三、模板渲染与数据传递
纯文本返回无法满足真实页面需求,Flask集成了Jinja2模板引擎,允许把Python变量嵌入HTML文件。模板放在项目根目录的templates文件夹中,用render_template函数加载并传入数据。
模板里可以用双大括号输出变量,用百分号括起来的块写控制语句。这样前端结构和后端逻辑分离,比在代码里拼字符串安全且易维护。以下示例展示后端传参和模板接收的方式。
<!-- templates/hello.html -->
<!DOCTYPE html>
<html>
<head><title>欢迎</title></head>
<body>
<h1>你好,{{ name }}!</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/list')
def list_view():
data = {'name': '访客', 'items': ['Python', 'Flask', 'Web']}
# 把字典里的键作为变量名传给模板
return render_template('hello.html', **data)
if __name__ == '__main__':
app.run()
使用模板后,HTML里的特殊字符默认会被转义,防止用户注入恶意脚本。如果确实要输出可信的富文本,可以使用| safe过滤器,但必须确保内容来源可靠。这种自动转义机制大幅降低了跨站脚本攻击的风险。
四、处理表单与请求数据
交互式网站离不开表单提交,Flask通过request对象获取用户发来的数据。无论是URL里的查询参数,还是POST过来的表单字段,都能从request中按名称提取。
下面的例子用同一个路由同时响应GET和POST方法。GET时返回表单页面,POST时读取输入框内容并回显。注意在route装饰器里要显式声明methods列表,否则默认只接受GET。
from flask import Flask, request, render_template_string
app = Flask(__name__)
form_tpl = '''
<form method="post">
姓名:<input type="text" name="username">
<input type="submit" value="提交">
</form>
{% if name %}<p>你提交了:{{ name }}</p>{% endif %}
'''
@app.route('/form', methods=['GET', 'POST'])
def handle_form():
name = None
if request.method == 'POST':
# 从表单字典里取字段
name = request.form.get('username')
return render_template_string(form_tpl, name=name)
if __name__ == '__main__':
app.run()
实际项目中表单通常配合WTForms等库做校验,防止空值或非法格式进入数据库。Flask本身只提供最基础的获取能力,把验证、防跨站请求伪造等任务交给扩展,这也体现了它“微框架”的设计哲学。
五、项目结构演进建议
当代码变多,把所有路由写在一个文件会难以维护。常见做法是按功能拆分蓝图(Blueprint),把用户、文章等模块分开。同时用工厂函数创建app,方便在测试时切换配置。
下表列出从小demo到中等规模应用的典型目录变化:
| 阶段 | 结构特点 | 适用场景 |
|---|---|---|
| 单文件 | 路由与配置都在app.py | 学习、接口原型 |
| 蓝图拆分 | 每个模块独立文件夹与views.py | 多页面站点 |
| 工厂模式 | create_app函数集中初始化 | 需要多环境部署 |
采用蓝图后,主文件只需注册各个模块,逻辑边界清晰。例如from user import user_bp然后app.register_blueprint(user_bp),就能把用户相关路由归拢到一起。这种渐进式架构让Flask既能做玩具项目,也能撑起正式产品。
FlaskPython_Web路由修改时间:2026-08-01 12:48:36