FastAPI+Beanie:输入输出模型间动态数据转换如何实现?
Beanie ODM实现存储ID与返回完整对象的动态转换
问题背景
为节省MongoDB存储空间,Book集合仅存储Author的ObjectId而非完整嵌套对象,但输出模型BookOut需要返回完整的Author对象。需求是实现存储ID到完整对象的动态转换,无需手动提取修改整个对象。
现有代码:
from beanie import Document, PydanticObjectId from pydantic import BaseModel class Author(Document): name: str email: str class Book(Document): title: str author: PydanticObjectId class BookOut(BaseModel): title: str author: Author | None = None
解决方案
方法1:使用Beanie原生Link字段(推荐)
Beanie提供的Link类型专门处理文档间的引用关联,支持自动加载关联文档,无需手动转换ID。
- 修改
Book模型,将author字段替换为Link[Author]:
from beanie import Document, Link class Book(Document): title: str author: Link[Author]
- 查询时加载关联的
Author文档:
# 查询单本图书并自动加载作者 book = await Book.get(book_id, fetch_links=True) # 批量查询所有图书并加载关联作者 books = await Book.find_all().fetch_all_links().to_list()
- 直接转换为
BookOut模型:
book_out = BookOut(**book.dict())
方法2:自定义异步验证器(手动处理)
如果不想依赖Link字段,可在BookOut模型中添加异步验证器,自动根据ID查询对应的Author。
- 修改
BookOut模型,添加字段验证器:
from pydantic import BaseModel, field_validator class BookOut(BaseModel): title: str author: Author | None = None @field_validator("author", mode="before") async def fetch_author(cls, value): # 若传入的是ObjectId,则查询对应的Author文档 if isinstance(value, PydanticObjectId): return await Author.get(value) return value
- 使用
from_orm异步转换模型:
book = await Book.get(book_id) # 注意需添加await,因为验证器是异步的 book_out = await BookOut.from_orm(book)
内容的提问来源于stack exchange,提问作者Harshith J.V.
相关产品推荐
相关产品推荐

