前置要求:Python基础、HTTP基础
学习时长:约2-3天(每天4小时)
Flask版本:3.0+
适用场景:小型API、原型开发、微服务、内部工具
一、Flask 是什么?
Flask 是 Python 最流行的轻量级Web框架,以简洁灵活著称,被称为"微框架"。
| 特点 | 说明 |
|---|---|
| 核心理念 | 简单、灵活、可扩展 |
| 学习曲线 | ★★☆☆☆(最容易上手的Web框架) |
| 适用场景 | 小型API、原型、微服务、内部工具 |
| 对比Django | 更轻量,没有ORM、Admin等内置功能 |
| 扩展生态 | Flask-SQLAlchemy、Flask-Login、Flask-CORS |
二、快速开始
# 安装Flask
pip install flask
# 项目结构
myproject/
├── app.py # 主应用
├── config.py # 配置文件
├── requirements.txt # 依赖
├── models/ # 数据模型
├── routes/ # 路由
├── templates/ # HTML模板
└── static/ # 静态文件
# app.py - 最简应用
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, Flask!'
if __name__ == '__main__':
app.run(debug=True, port=5000)
# 运行
python app.py
# 访问 http://localhost:5000
三、路由系统
from flask import Flask, request, jsonify, redirect, url_for
app = Flask(__name__)
# ====================
# 基本路由
# ====================
@app.route('/')
def index():
return '首页'
# ====================
# HTTP方法
# ====================
@app.route('/api/users', methods=['GET'])
def get_users():
return jsonify({'users': []})
@app.route('/api/users', methods=['POST'])
def create_user():
data = request.get_json()
return jsonify(data), 201
# ====================
# URL参数
# ====================
@app.route('/user/<int:user_id>')
def get_user(user_id):
return f'用户ID: {user_id}'
@app.route('/user/<string:username>')
def get_user_by_name(username):
return f'用户名: {username}'
# ====================
# 查询参数
# ====================
@app.route('/search')
def search():
keyword = request.args.get('keyword', '')
page = request.args.get('page', 1, type=int)
return f'搜索: {keyword}, 页码: {page}'
# ====================
# 重定向
# ====================
@app.route('/old-url')
def old_url():
return redirect(url_for('index'))
# ====================
# 错误处理
# ====================
@app.errorhandler(404)
def not_found(error):
return jsonify({'error': '页面不存在'}), 404
@app.errorhandler(500)
def internal_error(error):
return jsonify({'error': '服务器内部错误'}), 500
四、请求与响应
from flask import Flask, request, jsonify, make_response
app = Flask(__name__)
@app.route('/api/data', methods=['POST'])
def handle_data():
# ====================
# 获取请求数据
# ====================
# JSON数据
json_data = request.get_json()
# 表单数据
form_data = request.form.get('name')
# 查询参数
query_param = request.args.get('key')
# 文件上传
file = request.files.get('avatar')
# 请求头
token = request.headers.get('Authorization')
# ====================
# 返回响应
# ====================
# JSON响应
return jsonify({
'status': 'success',
'data': json_data
})
# 带状态码
return jsonify({'error': '参数错误'}), 400
# 自定义响应
response = make_response('自定义响应')
response.headers['X-Custom'] = 'value'
response.set_cookie('token', 'abc123')
return response
五、蓝图(模块化)
# ====================
# routes/user.py
# ====================
from flask import Blueprint, jsonify, request
user_bp = Blueprint('user', __name__, url_prefix='/api/users')
@user_bp.route('/', methods=['GET'])
def get_users():
return jsonify({'users': []})
@user_bp.route('/<int:user_id>', methods=['GET'])
def get_user(user_id):
return jsonify({'id': user_id})
# ====================
# routes/post.py
# ====================
from flask import Blueprint, jsonify
post_bp = Blueprint('post', __name__, url_prefix='/api/posts')
@post_bp.route('/', methods=['GET'])
def get_posts():
return jsonify({'posts': []})
# ====================
# app.py - 注册蓝图
# ====================
from flask import Flask
from routes.user import user_bp
from routes.post import post_bp
app = Flask(__name__)
app.register_blueprint(user_bp)
app.register_blueprint(post_bp)
六、SQLAlchemy ORM
pip install flask-sqlalchemy
# ====================
# models/user.py
# ====================
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
email = db.Column(db.String(100), unique=True, nullable=False)
password_hash = db.Column(db.String(255), nullable=False)
is_active = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
# 关联
posts = db.relationship('Post', backref='author', lazy='dynamic')
def to_dict(self):
return {
'id': self.id,
'username': self.username,
'email': self.email,
'is_active': self.is_active,
'created_at': self.created_at.isoformat()
}
# ====================
# app.py - 配置数据库
# ====================
from flask import Flask
from models.user import db
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:password@localhost/mydb'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
# 创建表
with app.app_context():
db.create_all()
# ====================
# CRUD操作
# ====================
# 创建
user = User(username='张三', email='zhangsan@example.com', password_hash='hashed')
db.session.add(user)
db.session.commit()
# 查询
users = User.query.all()
user = User.query.get(1)
user = User.query.filter_by(username='张三').first()
users = User.query.filter(User.age > 25).all()
# 分页
pagination = User.query.paginate(page=1, per_page=10)
users = pagination.items
total = pagination.total
# 更新
user.username = '李四'
db.session.commit()
# 删除
db.session.delete(user)
db.session.commit()
七、完整项目示例
# app.py
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
CORS(app)
# 模型
class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
completed = db.Column(db.Boolean, default=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
def to_dict(self):
return {
'id': self.id,
'title': self.title,
'completed': self.completed,
'created_at': self.created_at.isoformat()
}
# 创建表
with app.app_context():
db.create_all()
# API
@app.route('/api/todos', methods=['GET'])
def get_todos():
todos = Todo.query.order_by(Todo.created_at.desc()).all()
return jsonify([t.to_dict() for t in todos])
@app.route('/api/todos', methods=['POST'])
def create_todo():
data = request.get_json()
if not data or not data.get('title'):
return jsonify({'error': '标题不能为空'}), 400
todo = Todo(title=data['title'])
db.session.add(todo)
db.session.commit()
return jsonify(todo.to_dict()), 201
@app.route('/api/todos/<int:todo_id>', methods=['PUT'])
def update_todo(todo_id):
todo = Todo.query.get_or_404(todo_id)
data = request.get_json()
if 'title' in data:
todo.title = data['title']
if 'completed' in data:
todo.completed = data['completed']
db.session.commit()
return jsonify(todo.to_dict())
@app.route('/api/todos/<int:todo_id>', methods=['DELETE'])
def delete_todo(todo_id):
todo = Todo.query.get_or_404(todo_id)
db.session.delete(todo)
db.session.commit()
return jsonify({'message': '删除成功'})
if __name__ == '__main__':
app.run(debug=True)
学习建议
- 先跑通Hello World,理解请求-响应流程
- 重点掌握蓝图,组织好项目结构
- 学习SQLAlchemy,这是Flask最常用的ORM
- 做一个完整项目(Todo API或博客API)
- 学习部署:Gunicorn + Nginx