FastAPI教程-响应类型-返回JSON 作者:马育民 • 2026-08-14 20:31 • 阅读:10001 # 介绍 FastAPI **默认就返回 JSON**,内部基于 `JSONResponse`,自动做序列化、设置响应头 `Content-Type: application/json`。下面分常用写法、自定义响应、序列化规则、异常返回、底层原理。 # 1. 直接返回 dict 直接返回字典,FastAPI 自动转 JSON。 ### 例子 显示一条记录的详细信息,如:查看某个学生的信息 ```python from fastapi import FastAPI app = FastAPI() @app.get("/student") def get_student(): # 直接返回python字典,框架自动转为json return { "code": 200, "msg": "success", "data": { "name": "张三", "age": 20 } } ``` 响应结果: ```json { "code": 200, "msg": "success", "data": { "name": "张三", "age": 20 } } ``` # 2. 返回 Pydantic 模型(推荐) ### 例子1 直接返回模型对象,功能与返回 `dict` 类似,用于显示一条记录的详细信息,如:显示用户的信息 ```python from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class NoteResponse(BaseModel): id: int name: str password: str @app.get("/user") def get_user(): user = NoteResponse(id=1, name="李四",password="123456") return user # 返回模型对象,自动序列化为json ``` 响应结果: ```python { "id": 1, "name": "李四", "password": "123456" } ``` ### 缺点 **将密码也返回给前端了**,这是不合理的,**会泄露密码** ### 例子2:返回模型对象,过滤敏感字段 定义模型,**不包含 `password`**: ``` class NoteResponse(BaseModel): id: int name: str ``` 返回模型对象,既使在对象里 **加上 `password`,也不会返回**: ``` @app.get("/user") def get_user(): # 创建对象时传入 password user = NoteResponse(id=1, name="李四",password="123456") return user # 返回模型对象,自动序列化为json ``` 执行结果,**不包含 `password`**: ``` { "id": 1, "name": "李四" } ``` # 3. 设置 response_model 过滤敏感字段 很多场景:数据库模型字段很多,不想全部返回给前端,用 `response_model` 做输出过滤。 **注意:**既使返回 `dict`,也会过滤敏感字段 ### 例子 返回 `dict` 中包含 `password`,通过设置 `response_model`,会过滤掉 `password` 定义模型,**不包含 `password`**: ``` class NoteResponse(BaseModel): id: int name: str ``` 需要 **指定响应模型** `response_model`,返回 `dict`,既使 **加上 `password`,也不会返回**: ``` @app.get("/user",response_model=NoteResponse) def get_user(): return { "id":1, "name":"李四", "password":"123456" } ``` 执行结果,**不包含 `password`**: ``` { "id": 1, "name": "李四" } ``` # 4. 不输出未赋值的字段 还可以用 `response_model_exclude_unset=True`:不输出未赋值的字段。 ```python from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class NoteResponse(BaseModel): id: int # 要设置允许None,否则不设置值会报错 name: str | None = None age: int | None = None # 返回dict @app.get("/user",response_model=NoteResponse,response_model_exclude_unset=True) def get_user(): return { "id":1 } ``` 响应结果: ``` { "id": 1 } ``` # 5. 统一返回格式 前后端约定统一格式:`{code,msg,data}`,两种实现方式。 ### 方式1:每个接口手动包一层dict(简单小项目) ```python @app.get("/info") def info(): return { "code":200, "msg":"ok", "data":{ "name":"李雷", "age":18, } } ``` ### 方式2:封装工具函数(大项目) 手动构造 `JSONResponse`,可以自定义 **状态码**、**自定义响应头**、直接传入 `JSON` 字符串 ```python from fastapi.responses import JSONResponse def resp_ok(data=None,msg="success"): return JSONResponse({ "code":200, "msg":msg, "data":data }) def resp_fail(code=400,msg="fail",data=None): return JSONResponse({ "code":code, "msg":msg, "data":data }) @app.get("/test") def test(): return resp_ok(data={"name":"test"}) ``` # 底层流程 1. 视图函数 return 对象(dict/pydantic/list) 2. 调用 `jsonable_encoder()`:把ORM、Pydantic、datetime转成可序列化的python基础类型 3. 内部构建 `JSONResponse` 对象 4. 调用 `json.dumps()` 序列化为字节流 5. 设置响应头 `Content‑Type: application/json` 返回浏览器 **注意:**如果返回的本身就是 `Response`(如JSONResponse、HTMLResponse),**不会经过jsonable_encoder,直接输出**。 原文出处:/show_1GW3rXGXQYTK.html