Python Web开发:从Flask到FastAPI,我经历了什么
Python做Web后端框架选择一直是个热门话题。从最早的Django一统天下到Flask的轻量灵活再到FastAPI的异军突起每个框架都有自己的拥趸。这篇文章不吹不黑说说我用这几个框架的真实感受以及什么项目该选什么框架。一、Django大而全的工业级框架Django是我入行用的第一个Web框架。它的口号是为完美主义者打造的Web框架特点是功能极其全面。Django的优点开箱即用Django自带的东西太多了——ORM、Admin后台、表单验证、用户认证、Session管理、模板引擎、中间件……你几乎不需要自己选型拿来就能用。python# Django的ORM使用 from django.db import models class Article(models.Model): title models.CharField(max_length200) content models.TextField() pub_date models.DateTimeField(auto_now_addTrue) author models.ForeignKey(User, on_deletemodels.CASCADE) # 查询语法非常直观 articles Article.objects.filter(author__usernamezhangsan).order_by(-pub_date)Admin后台这是Django的杀手锏。只需要定义好Model一个功能完整的管理后台就自动生成了。对内部管理系统来说这简直是神器。python# admin.py from django.contrib import admin from .models import Article admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display (title, author, pub_date) search_fields (title, content) list_filter (pub_date, author)安全性Django内置了XSS、CSRF、SQL注入等防护开箱即安全。成熟生态第三方包极其丰富——django-rest-framework、django-celery、django-debug-toolbar……遇到问题搜一下基本都有答案。Django的缺点重Django太重了。一个最简单的项目也要加载一大堆东西启动慢内存占用高。不适合微服务或者资源受限的场景。不灵活Django有自己的一套哲学你最好按它的方式来。如果你想用SQLAlchemy替代Django的ORM那几乎是在跟框架作对。同步阻塞Django默认是同步的虽然支持异步3.0但生态还不成熟。适合的场景内容管理系统CMS企业级后台管理系统博客、新闻网站需要快速开发MVP的项目团队成员大多是Django老手的团队二、Flask小而精的灵活框架Django用了一段时间后我开始觉得它太笨重了。一个简单的API服务Django要加载一堆用不上的东西。于是我开始尝试Flask。Flask的核心哲学是微内核——它只提供最基础的功能路由、请求、响应其他的由你选择。Flask的优点轻量Flask的源码非常精简核心只有几千行。启动飞快内存占用小。灵活想用SQLAlchemy就用SQLAlchemy想用peewee就用peewee想用原生SQL也行。Flask从不强迫你用什么。pythonfrom flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy app Flask(__name__) app.config[SQLALCHEMY_DATABASE_URI] sqlite:///app.db db SQLAlchemy(app) app.route(/users/int:user_id, methods[GET]) def get_user(user_id): user User.query.get(user_id) if user is None: return jsonify({error: User not found}), 404 return jsonify(user.to_dict())易学Flask的设计非常简洁新手半小时就能上手。路由和视图函数的写法非常直观。扩展丰富Flask的生态虽然不如Django完整但也非常强大——Flask-SQLAlchemy、Flask-Migrate、Flask-Login、Flask-CORS等等。Flask的缺点选择困难因为太灵活了你需要自己选型。ORM用什么表单验证用什么权限管理用什么对于新手来说决策成本不低。大型项目缺乏规范Django有明确的目录结构和规范Flask没有。5个Flask项目可能5种组织方式团队协作时需要提前约定规范。性能一般Flask默认也是同步的并发能力一般。但可以通过Gunicorn 多Worker来提升。适合的场景RESTful API服务微服务原型验证简单网站对灵活性要求高的项目三、FastAPI异步时代的新宠这两年FastAPI火得不行。我用它重构过一个老的Flask项目性能提升了接近一倍代码量反而减少了。FastAPI的优点高性能FastAPI基于StarletteASGI和Pydantic性能直逼Node.js和Go。对于IO密集型场景大量API调用、数据库查询提升特别明显。pythonfrom fastapi import FastAPI, HTTPException from pydantic import BaseModel import asyncpg app FastAPI() class UserCreate(BaseModel): name: str email: str age: int app.post(/users) async def create_user(user: UserCreate): # 异步数据库操作 conn await asyncpg.connect(userpostgres, password...) result await conn.fetchrow( INSERT INTO users(name, email, age) VALUES($1, $2, $3) RETURNING id, user.name, user.email, user.age ) await conn.close() return {id: result[id], **user.dict()}自动生成API文档这是FastAPI最吸引人的特性之一。写好代码/docs和/redoc就自动生成了交互式API文档。pythonapp.get(/items/{item_id}) async def get_item(item_id: int, q: str | None None): 获取商品信息 - **item_id**: 商品ID - **q**: 可选的查询参数 return {item_id: item_id, q: q} # 访问 /docs 就能看到完整的文档数据校验基于Pydantic类型注解就是校验规则少写大量验证代码。异步支持原生async/await在处理IO操作时非常高效。FastAPI的缺点生态还不成熟相比Django和FlaskFastAPI的第三方扩展还不够丰富。异步ORM如SQLAlchemy异步版、Tortoise-ORM还在完善中。相对年轻遇到冷门问题Stack Overflow上可能找不到答案需要自己啃源码或提issue。同步代码兼容问题如果用了同步的库如requests会阻塞事件循环需要小心处理。适合的场景高并发API服务实时Web应用WebSocket机器学习模型服务FastAPI PyTorch/TensorFlow需要API文档规范的项目从零开始的新项目四、我的选型决策框架经过多年的实践我总结了一个简单的决策框架pythondef choose_framework(project): if project.is_enterprise_cms(): return Django elif project.is_microservice(): if project.requires_high_concurrency(): return FastAPI else: return Flask elif project.is_building_api(): if project.team_knows_async(): return FastAPI else: return Flask REST framework elif project.is_simple_site(): return Flask else: return FastAPI # 新项目默认选FastAPI更具体地说情况推荐内容型网站、后台管理DjangoREST API、微服务、高并发FastAPI小型项目、原型、灵活需求Flask需要WebSocketFastAPI需要实时流数据FastAPI团队对Python很熟但对Web不熟Django团队追求代码性能和现代化FastAPI五、实战对比同样的接口三种写法来一个实际的对比三个框架写同样的用户CRUD接口。Flask 版本pythonfrom flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy app Flask(__name__) db SQLAlchemy(app) class User(db.Model): id db.Column(db.Integer, primary_keyTrue) name db.Column(db.String(100)) email db.Column(db.String(100), uniqueTrue) app.route(/users/int:user_id, methods[GET]) def get_user(user_id): user User.query.get(user_id) if not user: return jsonify({error: User not found}), 404 return jsonify({id: user.id, name: user.name, email: user.email}) app.route(/users, methods[POST]) def create_user(): data request.get_json() user User(namedata[name], emaildata[email]) db.session.add(user) db.session.commit() return jsonify({id: user.id}), 201FastAPI 版本pythonfrom fastapi import FastAPI, HTTPException from pydantic import BaseModel, EmailStr from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession from sqlalchemy.orm import sessionmaker from sqlalchemy import select app FastAPI() class UserCreate(BaseModel): name: str email: EmailStr class UserResponse(BaseModel): id: int name: str email: str app.get(/users/{user_id}, response_modelUserResponse) async def get_user(user_id: int): async with AsyncSession(engine) as session: result await session.execute( select(User).where(User.id user_id) ) user result.scalar_one_or_none() if not user: raise HTTPException(404, User not found) return user app.post(/users, response_modelUserResponse, status_code201) async def create_user(user: UserCreate): async with AsyncSession(engine) as session: db_user User(**user.dict()) session.add(db_user) await session.commit() await session.refresh(db_user) return db_userFastAPI的版本多了类型注解、自动校验、自动文档代码更安全更规范。六、选择框架之外的建议不要迷信框架框架只是工具业务才是核心。考虑团队能力如果团队都是Flask老手突然切到FastAPI会有学习成本。考虑项目规模小项目选轻量框架大项目选全功能框架。不要过早优化很多项目根本到不了需要异步提升性能的阶段。技术选型不是一锤子买卖可以先用Flask快速验证后期再迁移到FastAPI。我们就是这么干的。写在最后三个框架没有绝对的好坏只有合不合适。Django像一个精装修的房子拎包入住但改造麻烦Flask像一个毛坯房你想怎么装修就怎么装修FastAPI像一个智能精装房现代、高效、自带各种智能功能如果你现在让我选一个新项目内部管理系统 → Django对外API服务 → FastAPI简单的Demo或工具 → Flask希望这篇文章能帮你做出合适的技术选型。