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

如何在Pydantic V2中用model_validate()为嵌套模型传递字段?

问题描述

现有SQLAlchemy数据库模型:

class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(sa.Integer(), primary_key=True)
    username: Mapped[str | None] = mapped_column(sa.String(64), nullable=True, index=True)
    email: Mapped[str | None] = mapped_column(sa.String(128), nullable=True)

尝试使用以下Pydantic V2模型序列化用户对象:

class PrivateDataSerializer(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    username: str | None
    email: str | None


class ProfileSerializer(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    private_data: PrivateDataSerializer

已将username和email字段放入嵌套的PrivateDataSerializer中,目标是通过ProfileSerializer.model_validate(user)加载用户对象,但无法正确配置private_data的字段映射。此前在Django DRF中,可通过为嵌套模型指定source="*"实现该需求:

class PrivateDataSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["username", "email"]


class ProfileSerializer(serializers.ModelSerializer):
    private_data = PrivateDataSerializer(source="*")

    class Meta:
        model = User
        fields = ["id", "private_data"]

请问如何在Pydantic V2中实现相同效果?

解决方案

在Pydantic V2中,可以通过模型验证器或计算字段实现类似DRF中source="*"的效果,核心是让嵌套模型直接从整个用户对象中提取所需字段。

方法一:前置模型验证器

通过@model_validator(mode='before')在验证流程启动前,将原始用户对象赋值给private_data字段,让嵌套模型自动解析所需字段:

from pydantic import model_validator

class PrivateDataSerializer(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    username: str | None
    email: str | None


class ProfileSerializer(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    private_data: PrivateDataSerializer

    @model_validator(mode='before')
    def populate_private_data(cls, data):
        # 将整个用户对象/数据字典传递给private_data字段
        data['private_data'] = data
        return data

使用时直接调用ProfileSerializer.model_validate(user)即可,private_data会自动从用户对象中提取username和email。

方法二:计算字段(更简洁)

利用Pydantic V2的@computed_field特性,自动基于当前关联的用户对象生成嵌套模型实例:

from pydantic import computed_field, ConfigDict

class PrivateDataSerializer(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    username: str | None
    email: str | None


class ProfileSerializer(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int

    @computed_field
    def private_data(self) -> PrivateDataSerializer:
        # 针对SQLAlchemy对象,直接传入原始实例;针对字典输入则解构传入
        if hasattr(self, '__pydantic_instance__'):
            return PrivateDataSerializer.model_validate(self.__pydantic_instance__)
        return PrivateDataSerializer(**self.__dict__)

这种方式无需手动修改验证流程,通过计算字段自动生成嵌套数据,代码更简洁直观。


内容的提问来源于stack exchange,提问作者goedwig

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:23:26