Python Flask 框架入门教程 — 轻量级Web框架

前置要求: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)


学习建议

  1. 先跑通Hello World,理解请求-响应流程
  2. 重点掌握蓝图,组织好项目结构
  3. 学习SQLAlchemy,这是Flask最常用的ORM
  4. 做一个完整项目(Todo API或博客API)
  5. 学习部署:Gunicorn + Nginx

下一步学习

返回首页