0%

FastAPI自学教程(27) - JSON兼容编码器

1. 基础用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from datetime import datetime
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
title: str
timestamp: datetime
description: str | None = None

@app.put("/items/{id}")
def update_item(id: str, item: Item):
json_data = jsonable_encoder(item)
return json_data
  • jsonable_encoder()是FastAPI内置的智能转换工具,可将Pydantic模型等复杂类型转换为JSON兼容格式的字典/列表
  • 自动处理类型转换逻辑:
    • datetime对象 → ISO 8601格式字符串(如”2025-04-25T14:30:45”)
    • UUID → 字符串
    • Pydantic模型 → 嵌套字典结构

2. 数据库存储场景

1
2
3
4
5
6
7
8
9
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["mydatabase"]

@app.put("/db-items/{id}")
def save_item(id: str, item: Item):
encoded_item = jsonable_encoder(item)
db["items"].insert_one({"_id": id, **encoded_item})
return {"status": "saved"}
  • 解决数据库不兼容特殊类型的问题(如MongoDB无法直接存储datetime对象)
  • 转换后的字典可直接用于数据库操作(如MongoDB的insert_one
  • 支持嵌套模型转换,保持数据结构完整性

3. 处理日期时间对象

1
2
3
4
5
6
7
8
9
from datetime import datetime

class Event(BaseModel):
name: str
start_time: datetime

event = Event(name="发布会", start_time=datetime(2025,4,25,20))
print(jsonable_encoder(event))
# 输出:{'name': '发布会', 'start_time': '2025-04-25T20:00:00'}
  • 自动将datetime转为符合ISO 8601标准的字符串
  • 支持datetime类型的转换(如datetime.date转为”2025-04-25”)
  • 时区感知:保留时区信息(如datetime.timezone.utc

4. 高级配置参数

1
2
3
4
5
6
7
8
# 排除默认值未设置的字段
jsonable_encoder(item, exclude_unset=True)

# 仅包含指定字段
jsonable_encoder(item, include={"title", "timestamp"})

# 排除特定字段
jsonable_encoder(item, exclude={"description"})
  • exclude_unset=True:过滤未显式赋值的可选字段
  • include/exclude参数:实现字段白名单/黑名单控制
  • 支持嵌套字段的过滤(如include={"user": {"name"}}

5. 注意事项

  1. 性能影响:深度嵌套的大型对象转换可能产生性能开销,建议测试关键路径
  2. 默认行为:不会转换Python基本类型(int/str/list等已兼容JSON的类型)
  3. 兼容性:与Pydantic V2的model_dump()方法配合使用效果更佳
  4. 扩展性:如需处理自定义类型,可通过继承json.JSONEncoder实现(需结合FastAPI配置)