使用pydantic_model_creator创建模型时排除多对多关联嵌套对象字段
问题根因
pydantic_model_creator的exclude参数不支持嵌套字段的点语法,因此直接写ingredients.not_needed无法生效- 自定义DTO时出现
ingredients value is not a valid list报错,是因为Tortoise默认懒加载多对多关联字段,未预取关联数据时,ingredients字段是M2MRelation代理对象,而非实际的Ingredient实例列表,Pydantic无法直接序列化该代理对象
解决方案
方案1:使用Tortoise官方Pydantic生成工具(无需自定义DTO)
先为关联的Ingredient单独生成排除了not_needed字段的Pydantic模型,再指定给Recipe的生成器使用:
from tortoise.contrib.pydantic import pydantic_model_creator # 先生成Ingredient的精简Pydantic模型,排除不需要的字段 IngredientInRecipe = pydantic_model_creator(Ingredient, exclude=("not_needed",)) # 生成Recipe的Pydantic模型,指定ingredients字段的类型为上面的精简模型列表 RecipePydantic = pydantic_model_creator( Recipe, # 这里按需添加你需要暴露的其他Recipe字段 include=("id", "name", "ingredients"), pydantic_type_hints={"ingredients": list[IngredientInRecipe]} )
注意:查询Recipe数据时必须添加prefetch_related预取关联的ingredients数据:
# 正确查询写法 recipes = await Recipe.all().prefetch_related("ingredients") # 序列化 recipe_data = RecipePydantic.from_orm(recipes[0])
方案2:修复自定义DTO的使用方式
你写的DTO结构完全正确,只需要在查询时预取关联数据即可,无需额外添加计算属性:
class IngredientInRecipeDTO(BaseModel): name: str class Config: orm_mode = True class RecipeDTO(BaseModel): # 补充你需要的其他Recipe字段,比如id、name等 id: int name: str ingredients: list[IngredientInRecipeDTO] class Config: orm_mode = True # 调用时只要预取数据即可正常序列化 recipes = await Recipe.all().prefetch_related("ingredients") recipe_dto = RecipeDTO.from_orm(recipes[0])
内容的提问来源于stack exchange,提问作者Rechu
相关产品推荐
相关产品推荐

