Pydantic 2.* 验证器将所有额外字段添加到唯一的字典字段

问题描述 投票:0回答:1

验证器和额外列在 pydantic 2.* 中都有不同的配置方式,我想知道我是否仍然可以进行验证以获取所有额外字段并将它们放入单个字典字段中

预期的行为是:

class A(BaseModel):
    name: str
    extra_columns: Optional[Dict]

a = A(name="john", age=24, address="Brazil")

print(a)

>>> A(name="john", extra_columns={"age": 24, "address": "Brazil"})

我之前的代码:

    @root_validator(pre=True)
    def build_extra(cls, values: Dict[str, Any]) -> Dict[str, Any]:
        all_required_field_names = {
            field.alias for field in cls.__fields__.values() if field.alias != "extra_columns"
        }

        extra: Dict[str, Any] = {}
        for field_name in list(values):
            if field_name not in all_required_field_names:
                extra[field_name] = values.pop(field_name)
        values["extra_columns"] = extra
        return values

是否可以在 pydantic 2.* 中采取相同的行为?

python validation pydantic
1个回答
0
投票

这可以通过model_validator来解决:

from typing import Any
from pydantic import BaseModel, model_validator

class A(BaseModel):
    name: str
    extra_columns: dict | None = None
    
    @model_validator(mode="before")
    @classmethod
    def set_extra_columns(cls, data: Any):
        if isinstance(data, dict):
            extra_fields = data.keys() - cls.model_fields.keys()
            if extra_fields:
                if "extra_columns" not in data:
                    data["extra_columns"] = {}
                data["extra_columns"].update(
                    {field_name: data[field_name] for field_name in extra_fields}
                )
        return data

a = A(name="john", age=24, address="Brazil")

print(a)

# >>> name='john' extra_columns={'age': 24, 'address': 'Brazil'}
© www.soinside.com 2019 - 2024. All rights reserved.