Jyo*_*may 28 python python-3.x pydantic
我在 Pydantic Config 中定义了 pydantic 架构extra = Extra.allow。
是否可以获取单独传递给架构的一个列表或一组额外字段。
例如:
from pydantic import BaseModel as pydanticBaseModel
class BaseModel(pydanticBaseModel):
name: str
class Config:
allow_population_by_field_name = True
extra = Extra.allow
Run Code Online (Sandbox Code Playgroud)
我传递以下 JSON:
{
"name": "Name",
"address": "bla bla",
"post": "post"
}
Run Code Online (Sandbox Code Playgroud)
我需要一个来自 的函数pydantic(如果可用),它将返回传递的所有额外字段。喜欢:{"address", "post"}
fla*_*kes 33
注意:此答案适用于 Pydantic 1.x 版本。有关 2.x 解决方案,请参阅robcxyz 的答案。
来自pydantic 文档:
额外的
在模型初始化期间是否忽略、允许或禁止额外属性。
'ignore'接受、'allow'、 或 的字符串值,'forbid'或枚举值Extra(默认值:Extra.ignore)。'forbid'如果包含额外的属性,将导致验证失败,'ignore'将默默地忽略任何额外的属性,并将'allow'属性分配给模型。
这可以包含在模型Config类中,也可以作为继承时的参数BaseModel。
from pydantic import BaseModel, Extra
class BaseModel(BaseModel, extra=Extra.allow):
name: str
model = Model.parse_obj(
{"name": "Name", "address": "bla bla", "post": "post"}
)
print(model)
# name='Name' post='post' address='bla bla'
Run Code Online (Sandbox Code Playgroud)
__fields__要获得额外的值,您可以做一些简单的事情,例如将类上定义的集合与__dict__实例上的值进行比较:
class Model(BaseModel, extra=Extra.allow):
python_name: str = Field(alias="name")
@property
def extra_fields(self) -> set[str]:
return set(self.__dict__) - set(self.__fields__)
Run Code Online (Sandbox Code Playgroud)
>>> Model.parse_obj({"name": "Name", "address": "bla bla", "post": "post"}).extra_fields
{'address', 'post'}
>>> Model.parse_obj({"name": "Name", "foobar": "fizz"}).extra_fields
{'foobar'}
>>> Model.parse_obj({"name": "Name"}).extra_fields
set()
Run Code Online (Sandbox Code Playgroud)
rob*_*xyz 22
Pydantic 额外字段行为在 2.0 版本中进行了更新。根据他们的文档,您现在不需要执行任何操作,只需将model_config extra字段设置为allow,然后可以使用该model_extra字段或__pydantic_extra__实例属性来获取额外字段的字典。
from pydantic import BaseModel, Field, ConfigDict
class Model(BaseModel):
python_name: str = Field(alias="name")
model_config = ConfigDict(
extra='allow',
)
m = Model(**{"name": "Name", "address": "bla bla", "post": "post"}).model_extra
assert m == {'address': 'bla bla', 'post': 'post'}
m = Model(**{"name": "Name", "foobar": "fizz"}).__pydantic_extra__
assert m == {'foobar': 'fizz'}
m = Model(**{"name": "Name"}).__pydantic_extra__
assert m == {}
Run Code Online (Sandbox Code Playgroud)
ale*_*ame 18
据我所知,对此没有现成的解决方案。但是,由于您可以访问pre 根验证器中的所有“原始”传递数据,包括额外的字段,因此您可以将它们放在单独的字典中。
一个例子是从这里获取的。感谢@PrettyWood 提供:
from typing import Any, Dict, Optional
from pydantic import BaseModel, Field, root_validator
class ComposeProject(BaseModel):
version: Optional[str] = Field(alias='version') # just to show that it supports alias too
extra: Dict[str, Any]
@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'} # to support alias
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'] = extra
return values
project = ComposeProject(**{
"version": "3",
"services": ...
})
print(project.version) # => '3'
print(project.extra) # => {'services': Ellipsis}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30307 次 |
| 最近记录: |