You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pydantic_model_creator创建模型时排除多对多关联嵌套对象字段

问题根因
  1. pydantic_model_creator的exclude参数不支持嵌套字段的点语法,因此直接写ingredients.not_needed无法生效
  2. 自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 16:21:01