Flask 是一个使用 Python 编写的轻量级 Web 应用框架。它"微"(micro)的含义是 Flask 保持核心简单但可扩展,让你可以根据需要选择合适的工具和库。
一、为什么选择 Flask?
优势 |
说明 |
✅ 轻量级 |
核心简单,学习曲线平缓 |
✅ 灵活性 |
可自由选择数据库、模板引擎等组件 |
✅ Pythonic |
代码简洁,符合 Python 哲学 |
✅ 强大扩展 |
拥有丰富的第三方扩展 |
✅ 适合学习 |
理解 Web 开发基础概念的理想选择 |
💡 适用场景:小型网站、API 服务、学习 Web 开发、原型开发
二、环境准备
1. 安装 Python
确保已安装 Python 3.6+:
python --version
# 或
python3 --version
2. 创建虚拟环境(推荐)
# 创建虚拟环境
python -m venv flask-env
# 激活虚拟环境
# Windows:
flask-env\Scripts\activate
# macOS/Linux:
source flask-env/bin/activate
3. 安装 Flask
pip install Flask
验证安装:
python -c "import flask; print(flask.__version__)"
三、第一个 Flask 应用
1. 基础应用结构
创建文件 app.py
:
from flask import Flask
# 创建 Flask 应用实例
app = Flask(__name__)
# 定义路由和视图函数
@app.route('/')
def hello():
return 'Hello, Flask!'
# 运行应用
if __name__ == '__main__':
app.run(debug=True)
2. 运行应用
python app.py
访问 http://127.0.0.1:5000
,你应该能看到 "Hello, Flask!"
🔥 关键概念:
Flask(__name__)
:创建应用实例@app.route()
:装饰器,定义 URL 路由debug=True
:开启调试模式,代码修改后自动重启
四、路由与视图
1. 基本路由
@app.route('/')
def index():
return '<h1>首页</h1>'
@app.route('/about')
def about():
return '<h1>关于</h1>'
2. 变量规则
@app.route('/user/<username>')
def show_user(username):
return f'用户: {username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'文章ID: {post_id}'
支持的类型转换器:
string
:(默认)接受任何不包含斜杠的文本int
:整数float
:浮点数path
:类似 string,但接受斜杠uuid
:UUID 字符串
3. HTTP 方法
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return '处理登录表单'
else:
return '''
<form method="post">
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<input type="submit" value="登录">
</form>
'''
4. URL 构建
from flask import url_for
@app.route('/admin')
def admin():
return '管理员页面'
@app.route('/link')
def link():
# 生成 URL
admin_url = url_for('admin')
return f'<a href="{admin_url}">进入管理后台</a>'
五、模板渲染(Jinja2)
Flask 使用 Jinja2 模板引擎。
1. 创建模板目录
your-project/
├── app.py
└── templates/
└── index.html
2. 创建模板文件 templates/index.html
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
<p>欢迎,{{ name }}!</p>
<!-- 条件语句 -->
{% if age >= 18 %}
<p>您已成年</p>
{% else %}
<p>您未成年</p>
{% endif %}
<!-- 循环 -->
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
3. 渲染模板
from flask import render_template
@app.route('/hello/<name>')
def hello_template(name):
return render_template(
'index.html',
title='欢迎页面',
name=name,
age=25,
items=['苹果', '香蕉', '橙子']
)
4. 模板继承
创建基础模板 templates/base.html
:
<!DOCTYPE html>
<html>
<head>
{% block title %}<title>默认标题</title>{% endblock %}
</head>
<body>
<nav>
<a href="{{ url_for('index') }}">首页</a>
<a href="{{ url_for('about') }}">关于</a>
</nav>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
创建子模板 templates/about.html
:
{% extends "base.html" %}
{% block title %}<title>关于我们</title>{% endblock %}
{% block content %}
<h1>关于我们</h1>
<p>这里是关于页面的内容...</p>
{% endblock %}
六、请求与响应处理
1. 处理请求数据
from flask import request, jsonify
@app.route('/api/data', methods=['POST'])
def handle_data():
# 获取 JSON 数据
data = request.get_json()
# 获取表单数据
username = request.form.get('username')
password = request.form.get('password')
# 获取查询参数
page = request.args.get('page', 1, type=int)
return jsonify({
'received': data,
'username': username,
'page': page
})
2. 返回不同类型的响应
from flask import jsonify, make_response, send_file
# JSON 响应
@app.route('/api/user')
def api_user():
return jsonify({'name': '张三', 'age': 30})
# 自定义响应
@app.route('/custom')
def custom_response():
response = make_response('<h1>自定义响应</h1>', 201)
response.headers['X-Custom-Header'] = 'Value'
return response
# 文件响应
@app.route('/download')
def download_file():
return send_file('path/to/file.pdf', as_attachment=True)
七、静态文件
Flask 自动提供 static
文件夹中的文件。
目录结构:
your-project/
├── app.py
├── static/
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── logo.png
└── templates/
在模板中使用:
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
<img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo">
八、表单处理
1. 简单表单处理
from flask import request, redirect, url_for, flash
@app.route('/contact', methods=['GET', 'POST'])
def contact():
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
message = request.form['message']
# 验证数据
if not name or not email:
flash('请填写必填字段!')
return redirect(url_for('contact'))
# 处理表单数据(如发送邮件、保存到数据库)
save_message(name, email, message)
flash('消息已发送!')
return redirect(url_for('contact'))
return '''
<form method="post">
<input type="text" name="name" placeholder="姓名" required><br>
<input type="email" name="email" placeholder="邮箱" required><br>
<textarea name="message" placeholder="消息"></textarea><br>
<input type="submit" value="发送">
</form>
'''
2. 使用 Flask-WTF(推荐)
安装:
pip install Flask-WTF
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, SubmitField
from wtforms.validators import DataRequired, Email
class ContactForm(FlaskForm):
name = StringField('姓名', validators=[DataRequired()])
email = StringField('邮箱', validators=[DataRequired(), Email()])
message = TextAreaField('消息')
submit = SubmitField('发送')
@app.route('/contact', methods=['GET', 'POST'])
def contact_wtf():
form = ContactForm()
if form.validate_on_submit():
# 处理表单数据
save_message(form.name.data, form.email.data, form.message.data)
flash('消息已发送!')
return redirect(url_for('contact_wtf'))
return render_template('contact.html', form=form)
模板 templates/contact.html
:
<form method="post">
{{ form.hidden_tag() }}
<p>
{{ form.name.label }}<br>
{{ form.name(size=32) }}
{% for error in form.name.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.email.label }}<br>
{{ form.email(size=32) }}
{% for error in form.email.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.message.label }}<br>
{{ form.message(rows=4, cols=32) }}
</p>
<p>{{ form.submit() }}</p>
</form>
九、数据库集成(Flask-SQLAlchemy)
1. 安装
pip install Flask-SQLAlchemy
2. 配置和模型
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 配置数据库(这里使用 SQLite)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# 定义模型
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f'<User {self.username}>'
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
user = db.relationship('User', backref=db.backref('posts', lazy=True))
3. 数据库操作
@app.route('/users', methods=['GET', 'POST'])
def users():
if request.method == 'POST':
# 创建新用户
username = request.form['username']
email = request.form['email']
user = User(username=username, email=email)
db.session.add(user)
db.session.commit()
flash('用户创建成功!')
# 查询所有用户
users = User.query.all()
return render_template('users.html', users=users)
@app.route('/users/<int:user_id>')
def user_detail(user_id):
user = User.query.get_or_404(user_id)
return render_template('user_detail.html', user=user)
4. 初始化数据库
# 在 Python 交互环境中
from app import db
db.create_all() # 创建所有表
十、用户认证(Flask-Login)
1. 安装
pip install Flask-Login
2. 配置
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
# 用户模型需要继承 UserMixin
class User(UserMixin, db.Model):
# ... 其他字段
pass
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
user = User.query.filter_by(username=username).first()
if user and check_password(password, user.password): # 实际需要密码哈希
login_user(user)
return redirect(url_for('dashboard'))
else:
flash('用户名或密码错误')
return render_template('login.html')
@app.route('/dashboard')
@login_required # 装饰器确保用户已登录
def dashboard():
return f'欢迎,{current_user.username}!'
@app.route('/logout')
def logout():
logout_user()
return redirect(url_for('index'))
十一、项目结构建议
对于稍大的项目,建议使用包结构:
my_flask_app/
├── app/
│ ├── __init__.py
│ ├── models.py
│ ├── routes.py
│ ├── forms.py
│ └── templates/
│ └── ...
├── migrations/ # 数据库迁移
├── static/
├── tests/
├── config.py
└── run.py
app/__init__.py
:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config.from_object('config.Config')
db.init_app(app)
from app.routes import main_bp
app.register_blueprint(main_bp)
return app
run.py
:
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
十二、常用扩展
扩展 |
用途 |
|
表单处理和验证 |
|
数据库 ORM |
|
数据库迁移 |
|
用户认证 |
|
邮件发送 |
|
构建 REST API |
|
处理跨域请求 |
|
缓存支持 |
安装扩展:
pip install Flask-WTF Flask-SQLAlchemy Flask-Migrate Flask-Login
十三、部署准备
1. 环境变量
创建 .env
文件:
FLASK_APP=app.py
FLASK_ENV=production
SECRET_KEY=your-secret-key-here
DATABASE_URL=sqlite:///prod.db
2. 生产服务器
不要使用 Flask 内置服务器进行生产部署。推荐使用:
Gunicorn:
pip install gunicorn
gunicorn -w 4 app:app
uWSGI:
pip install uwsgi
uwsgi --http :5000 --wsgi-file app.py --callable app
3. 与 Nginx 配合
Nginx 作为反向代理,处理静态文件和负载均衡。
十四、学习资源
- 官方文档:Welcome to Flask — Flask Documentation (3.1.x)
- Flask 教程:Tutorial — Flask Documentation (3.1.x)
- Real Python Flask 教程:Flask Tutorials – Real Python
- 《Flask Web 开发》:Miguel Grinberg 著
十五、总结
Flask 特性 |
说明 |
轻量核心 |
只包含最基本的功能 |
灵活扩展 |
通过扩展添加所需功能 |
开发友好 |
调试模式、开发服务器 |
社区活跃 |
丰富的文档和第三方库 |
适合学习 |
理解 Web 开发基础 |
Flask 是学习 Python Web 开发的绝佳起点。它让你从基础开始,逐步构建复杂的应用,同时保持代码的清晰和可维护性。