在使用 FastAPI 时,我们通常会接收到客户端传来的 JSON 请求体。FastAPI 会根据我们声明的 Pydantic 模型,自动完成数据解析、类型转换和校验,并将请求体转换成对应的 Pydantic 模型对象。

但在实际开发中,我们有时也需要把 Pydantic 对象转换成更通用的 dict,或者把 dict、JSON 字符串和 Pydantic 对象互相转换。

在较新的 Pydantic 版本,也就是 Pydantic v2+ 中,dict() 方法虽然仍可使用,但已经不推荐作为主要写法。更推荐使用 model_dump()。相比 dict()model_dump() 语义更清晰,表示“将模型对象导出为普通 Python 数据结构”。

数据类型之间的关系

1. Python 字典:dict

dict 是 Python 内置的数据结构,用于存储键值对,适合在 Python 代码内部直接操作。

示例:

1
{"name": "Alice", "age": 30}

2. JSON 字符串

JSON 是一种文本格式,常用于网络传输、接口通信和数据存储。

示例:

1
'{"name": "Alice", "age": 30}'

需要注意的是,JSON 本质上是字符串格式,不是 Python 字典。它只能表示一些通用数据类型,例如字符串、数字、布尔值、null、数组和对象。

3. Pydantic 模型对象

Pydantic 模型对象是基于 BaseModel 创建的 Python 类实例。它不仅可以存储数据,还可以进行类型校验、类型转换和结构约束。

示例:

1
Book(id=1, title="1984", author="George Orwell")

数据类型之间的转换

1. Pydantic 对象 → 字典

1
2
3
4
5
6
7
8
9
10
11
12
13
from pydantic import BaseModel

class Book(BaseModel):
id: int
title: str

book = Book(id=1, title="1984")

# Pydantic v2 推荐写法
book_dict = book.model_dump()

print(book_dict)
# {'id': 1, 'title': '1984'}

2. 字典 → Pydantic 对象

1
2
3
4
5
6
7
book_data = {"id": 1, "title": "1984"}

# Pydantic v2 推荐写法
book = Book.model_validate(book_data)

# 也可以使用普通实例化方式
book = Book(**book_data)

在 Pydantic v1 中,常见写法是:

1
book = Book.parse_obj(book_data)

但在 Pydantic v2 中,更推荐使用:

1
book = Book.model_validate(book_data)

3. 字典 / Pydantic 对象 → JSON

字典转 JSON 字符串:

1
2
3
4
5
import json

book_dict = {"id": 1, "title": "1984"}

json_str = json.dumps(book_dict)

Pydantic 对象转 JSON 字符串:

1
json_str = book.model_dump_json()

也可以先转成字典,再用 json.dumps()

1
json_str = json.dumps(book.model_dump())

但如果目标是直接得到 JSON 字符串,Pydantic v2 中更推荐使用:

1
book.model_dump_json()

4. JSON → 字典 / Pydantic 对象

JSON 字符串转字典:

1
2
3
4
5
import json

json_str = '{"id": 1, "title": "1984"}'

book_dict = json.loads(json_str)

JSON 字符串直接转 Pydantic 对象:

1
book = Book.model_validate_json(json_str)

也可以先把 JSON 转成字典,再把字典转成 Pydantic 对象:

1
2
book_dict = json.loads(json_str)
book = Book.model_validate(book_dict)

FastAPI 中的自动处理

FastAPI 会自动处理很多转换过程。

请求时

当我们在接口函数中声明 Pydantic 模型参数时,FastAPI 会自动读取请求体中的 JSON 数据,并将其转换成对应的 Pydantic 对象。

1
2
3
4
5
6
7
8
9
10
11
12
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Book(BaseModel):
id: int
title: str

@app.post("/books")
def create_book(book: Book):
return book

客户端发送:

1
2
3
4
{
"id": 1,
"title": "1984"
}

FastAPI 会自动把这段 JSON 请求体转换成 Book 对象。

响应时

当接口返回 Pydantic 对象、字典、列表等数据时,FastAPI 会自动将其序列化为 JSON 响应。

1
2
3
@app.get("/books/1")
def get_book():
return Book(id=1, title="1984")

返回结果会被转换成 JSON:

1
2
3
4
{
"id": 1,
"title": "1984"
}

小结

可以这样记:

1
JSON 字符串  <--->  dict  <--->  Pydantic 对象

常见转换方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# dict -> JSON
json.dumps(data)

# JSON -> dict
json.loads(json_str)

# dict -> Pydantic 对象
Book.model_validate(data)

# JSON -> Pydantic 对象
Book.model_validate_json(json_str)

# Pydantic 对象 -> dict
book.model_dump()

# Pydantic 对象 -> JSON
book.model_dump_json()

其中:

  • dict 适合 Python 代码内部操作
  • JSON 适合网络传输、接口通信和数据存储
  • Pydantic 对象 适合数据校验、类型转换和结构化约束

本站由 楠瓜 使用 Stellar 1.33.1 主题创建。
风起于青萍之末,浪成于微澜之间。