Flask框架入门:从安装到模板渲染
说实话,Flask是我个人最喜欢的Python Web框架之一。它轻量、灵活,不像Django那样「全家桶」式的沉重。我在做微服务架构时,经常拿Flask来搭API网关——启动快,配置少,几分钟就能跑起来。
这一章,咱们就从头捋一遍Flask的核心概念。你跟着我走一遍,保证能上手。
1. Flask安装
安装Flask其实就一行命令。但我建议你永远在虚拟环境里操作。为什么?因为不同项目依赖的Flask版本可能不一样,你总不想因为一个项目升级而搞崩另一个吧?
pip install flask
嗯,就这么简单。装完之后,你可以验证一下:
python -c "import flask; print(flask.__version__)"
如果没报错,说明装好了。我曾经遇到过一个问题——装完Flask后运行报错,结果发现是Python版本太老。Flask 2.0以上需要Python 3.6+,这点要注意。
2. 路由与视图函数
路由,说白了就是URL到函数的映射。你访问一个网址,Flask根据你访问的路径,找到对应的函数去处理,然后返回结果。
看个最简单的例子:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)
这里 @app.route('/') 就是路由装饰器。它告诉Flask:当用户访问根路径时,执行 home() 这个函数。
路由可以带参数。比如你想做一个用户个人主页:
@app.route('/user/<username>')
def user_profile(username):
return f'你好,{username}!欢迎来到你的主页。'
你想想看,这样是不是很灵活?不同的用户访问 /user/张三 和 /user/李四,返回的内容就不一样。
路由还支持指定HTTP方法:
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return '处理登录请求'
return '显示登录页面'
3. 请求与响应对象
Flask把HTTP请求封装成了 request 对象。你从请求里拿数据,全靠它。
我刚开始用Flask时,总记不住怎么取参数。后来总结了一个口诀:
- URL参数(GET):
request.args.get('key') - 表单数据(POST):
request.form.get('key') - JSON数据:
request.get_json() - 请求头:
request.headers.get('User-Agent')
举个例子,一个处理JSON的API:
from flask import request, jsonify
@app.route('/api/data', methods=['POST'])
def handle_data():
data = request.get_json()
if not data:
return jsonify({'error': '请提供JSON数据'}), 400
name = data.get('name', '匿名')
return jsonify({'message': f'收到数据,来自{name}'})
响应方面,Flask默认返回字符串。但实际项目中,我们更多用 jsonify() 返回JSON,或者用 make_response() 自定义响应头。
from flask import make_response
@app.route('/custom')
def custom_response():
resp = make_response('自定义响应', 200)
resp.headers['X-Custom-Header'] = 'Hello'
return resp
request.args 取数据,结果死活拿不到。记住:POST数据在 request.form 或 request.get_json() 里,别搞混了。
4. 模板渲染
Flask默认使用Jinja2模板引擎。模板渲染,就是把HTML模板和动态数据结合起来,生成最终的HTML页面。
首先,在项目根目录下创建 templates 文件夹。Flask会自动去那里找模板文件。
写一个简单的模板 templates/index.html:
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>欢迎,{{ name }}!</h1>
<p>今天是 {{ date }}</p>
</body>
</html>
然后在视图函数里渲染它:
from flask import render_template
from datetime import datetime
@app.route('/greet/<name>')
def greet(name):
return render_template('index.html',
title='欢迎页',
name=name,
date=datetime.now().strftime('%Y-%m-%d'))
Jinja2模板支持很多高级功能,比如循环、条件判断:
<ul>
{% for item in items %}
<li>{{ item.name }} - {{ item.price }}元</li>
{% endfor %}
</ul>
{% if user.is_admin %}
<p>管理员专属内容</p>
{% endif %}
我个人习惯把模板里的逻辑尽量简化。复杂的处理放在视图函数里完成,模板只负责展示。这样代码好维护,也容易调试。
base.html 作为布局,其他页面继承它。这样改导航栏、页脚时,只改一个文件就够了。
5. 实战小例子:一个简单的留言板
把上面学的东西串起来,写个迷你留言板:
from flask import Flask, request, render_template, redirect, url_for
app = Flask(__name__)
messages = [] # 用列表存留言,实际项目会用数据库
@app.route('/')
def index():
return render_template('board.html', messages=messages)
@app.route('/post', methods=['POST'])
def post_message():
content = request.form.get('content', '').strip()
if content:
messages.append(content)
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
模板 board.html:
<!DOCTYPE html>
<html>
<head>
<title>留言板</title>
</head>
<body>
<h1>留言板</h1>
<form method="POST" action="/post">
<input type="text" name="content" placeholder="写点什么...">
<button type="submit">发布</button>
</form>
<hr>
<h2>已有留言</h2>
<ul>
{% for msg in messages %}
<li>{{ msg }}</li>
{% endfor %}
</ul>
</body>
</html>
你看,不到30行代码,一个能用的留言板就出来了。这就是Flask的魅力——简单、直接、高效。