Python技术迷

Python生态在悄悄改变:FastAPI全面反超,Django和Flask还行吗?

新项目一开,我现在很少第一反应去建 Django 项目了。

不是 Django 不行,也不是 Flask 过气了,而是很多 Python 后端项目已经变了味:不再是一个后台管理系统带几个页面,而是一堆接口、回调、任务、AI 服务、内部平台、网关转发。

这种项目,FastAPI 上来就顺手。

我说的“反超”,不是说 FastAPI 在所有公司、所有老项目里把 Django 和 Flask 干掉了。老系统没那么容易换。真正反超的是新项目里的默认选择顺序。

以前问 Python Web 框架,脑子里基本是:

Django 做大项目。

Flask 做小服务。

现在很多人会先问一句:这个接口要不要类型校验?要不要自动文档?有没有异步请求?有没有模型入参?

这一问,FastAPI 就站到前面了。

Stack Overflow 2025 开发者调查里,FastAPI 被提到是 Web 框架里增长很明显的一项,而且满意度也很高。JetBrains 的 Python 开发者调查里,开发者希望 IDE 加强支持的框架中,FastAPI 也排在 Django 和 Flask 前面。PyPI Stats 上也能看到 FastAPI 下载趋势还在往上走,Django 更稳,Flask 相对没那么猛。这个方向基本已经很清楚了。

我平时看一个 Python Web 项目,第一眼会看接口入口。

Flask 代码经常长这样:

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.post("/orders/query")
defquery_orders():
    body = request.get_json() or {}

    user_id = body.get("user_id")
    page = int(body.get("page", 1))

ifnot user_id:
return jsonify({"code": 400, "msg": "user_id required"}), 400

    rows = load_orders(user_id=user_id, page=page)
return jsonify({"code": 0, "data": rows})

这段没毛病,Flask 就是这个味道,轻,直接,不管你太多。

但问题也在这里。

page 是不是数字,user_id 是不是空字符串,返回结构有没有统一,接口文档谁维护,都要你自己补。小服务没事,接口一多,这些“自己补”的地方最后都会散到各个文件里。

FastAPI 的写法,我更愿意在新接口里这么落:

from typing import Annotated
from fastapi import FastAPI, Header, HTTPException
from pydantic import BaseModel, Field

app = FastAPI()


classOrderQuery(BaseModel):
    user_id: str = Field(min_length=1)
    page: int = Field(default=1, ge=1, le=200)
    only_unpaid: bool = False


classOrderItem(BaseModel):
    order_no: str
    amount: int
    status: str


@app.post("/orders/query", response_model=list[OrderItem])
defquery_orders(
    query: OrderQuery,
    trace_id: Annotated[str | None, Header(alias="x-trace-id")] = None,
)
:

if query.user_id.startswith("tmp_"):
raise HTTPException(status_code=403, detail="temp user blocked")

    print(f"trace={trace_id} query_orders user={query.user_id} page={query.page}")

return load_order_items(
        user_id=query.user_id,
        page=query.page,
        only_unpaid=query.only_unpaid,
    )

这段代码我比较放心。

不是因为它看着新,而是很多脏活被框架提前卡住了:入参校验、类型转换、响应结构、OpenAPI 文档。FastAPI 官方文档也明确把类型注解、自动文档、OpenAPI 这些作为核心能力。

这里有个变化挺关键。

以前 Python 写接口,很多项目是“跑起来再说”。现在不行了,前端要根据接口文档联调,测试要根据 schema 造数据,AI 服务还经常把模型输入输出串起来。你再靠口头约定字段,迟早吵架。

FastAPI 讨巧的地方就在这:它把 Python 类型提示这套东西吃得比较狠。

写 int,它就按 int 校验。

写 BaseModel,它就按模型解析。

写 response_model,它就把返回也管起来。

这不是语法糖,这会影响接口质量。

但我也不赞成那种“FastAPI 出来以后 Django 没用了”的说法。这个判断太轻了,一看就没维护过后台系统。

Django 还是很能打,尤其是这种项目:

有用户体系。

有权限。

有后台管理。

有表单。

有 ORM。

有一堆运营同学每天要查数据、改状态、导 CSV。

这种场景你用 FastAPI 从零攒,也不是不行,但你要自己补很多东西。Django 官方定位本来就是高层 Web 框架,很多 Web 开发里的麻烦事它直接给你处理掉。

我见过一些团队,新项目一听 FastAPI 火,就把管理后台也拿 FastAPI 写,最后自己造登录、造权限、造菜单、造审计日志、造操作记录。

写到第三周就开始怀念 Django Admin。

这个时候不是框架选型先进,是没算账。

Flask 也一样。

Flask 最大的价值不是“老”,而是克制。官方文档里说它是轻量 WSGI Web 框架,适合快速开始,也能扩展到复杂应用。这个描述挺准。

我一般会在两种地方继续用 Flask。

一种是特别小的内部工具,比如临时接个 webhook,转发一下数据,挂个健康检查。

另一种是老项目已经稳定了,团队也熟。你硬把 Flask 换成 FastAPI,除了简历好看,线上风险大概率更高。

真正该警惕的是这种 Flask 项目:

@app.post("/callback/pay")
defpay_callback():
    payload = request.json
    save_raw_callback(payload)

if payload["status"] == "SUCCESS":
        mark_order_paid(payload["orderNo"], payload["paidTime"])

return"ok"

这代码第一眼看着能跑,我第一眼就不太信。

request.json 为空怎么办?

orderNo 字段改名怎么办?

重复回调怎么办?

金额有没有校验?

支付回调这种接口,不是能返回 ok 就完事了。

换成 FastAPI,我至少会先把边界拦住:

from decimal import Decimal
from pydantic import BaseModel, Field


classPayCallback(BaseModel):
    order_no: str = Field(min_length=8)
    amount: Decimal = Field(gt=0)
    status: str
    paid_at: str
    sign: str


@app.post("/callback/pay")
defpay_callback(event: PayCallback):
ifnot verify_pay_sign(event):
raise HTTPException(status_code=401, detail="bad sign")

if event.status != "SUCCESS":
        record_pay_noise(event.order_no, event.status)
return {"ok": True}

    changed = mark_paid_once(
        order_no=event.order_no,
        amount=event.amount,
        paid_at=event.paid_at,
    )

    print(f"pay_callback order={event.order_no} changed={changed}")
return {"ok": True}

这里不是 FastAPI 多神,而是它逼着你把接口边界写出来。

字段是什么,类型是什么,失败怎么报,文档长什么样,都比较清楚。

Python 生态这几年其实一直在往“工程化”走。类型提示、Pydantic、异步 IO、OpenAPI、自动生成客户端,这些东西合在一起,才把 FastAPI 推起来。

Django 和 Flask 当年解决的是另一批问题。

Django 解决的是:我想快速做一个完整 Web 应用。

Flask 解决的是:我想少受框架限制,自己拼。

FastAPI 解决的是:我想快速做一批可靠 API,而且这些 API 最好天然带类型、校验和文档。

所以现在选型,我会这么看。

后台系统、内容管理、运营平台,Django 依然稳。

临时服务、小工具、老项目扩展,Flask 依然够用。

新 API 服务、AI 接口、数据中台、前后端分离项目,我会优先看 FastAPI。

别为了追新换框架,也别因为老框架熟就一直不动。

框架这东西,最后还是要落到代码现场。

接口入参乱不乱,异常有没有兜住,文档是不是跟代码一致,线上出了问题能不能顺着 trace 找回来。

这些地方,FastAPI 确实更贴近现在 Python 后端的工作方式。

Django 和 Flask 还行吗?

当然还行。