我正在尝试制作一个 Pydantic 模型,该模型大部分是可变的,但我希望其中一个成员是不可变的。
型号
# Built In
from datetime import datetime
# 3rd Party
from pydantic import BaseModel
from pydantic import Field # https://pydantic-docs.helpmanual.io/usage/schema/#field-customisation
class Processor(BaseModel):
""" Pydantic model for a Processor object within the database. """
class Config:
"""
Model Configuration: https://pydantic-docs.helpmanual.io/usage/model_config/
"""
extra = 'forbid'
allow_mutation = True # This allows mutation, cool
validate_assignment = True
underscore_attrs_are_private = True
model: str
created_at: str = Field(default_factory=datetime.utcnow().isoformat) # I want to make sure that this can be passed but not assignable
updated_at: str
version: int = 0
expires: Optional[int] = None
我的目标是允许从对象(或默认对象)解析created_at
,但防止在创建模型后对其进行分配。
示例
example_object = {
"model": "foobar_model",
"created_at": "2020-12-22T15:35:06.262454+00:00",
"updated_at": "2020-12-22T15:35:06.262454+00:00",
"version": 2,
"expires": None
}
processor = Processor.parse_obj(example_object)
processor.version = 3 # This should be allowed
processor.created_at = datetime.utcnow().isoformat() # This I want to fail
相关但不是我要找的 - GitHub:Is there a way to have a single field be static and immutable with pydantic
我最终通过以下问题的答案解决了这个问题: https://github.com/samuelcolvin/pydantic/issues/2217
最佳答案
以下内容不起作用:
您可以将私有(private)属性与属性装饰器结合使用。私有(private)属性不包含在模型字段中,但可以通过属性访问。
from pydantic import BaseModel, PrivateAttr
class Processor(BaseModel):
""" Pydantic model for a Processor object within the database. """
class Config:
"""
Model Configuration: https://pydantic-docs.helpmanual.io/usage/model_config/
"""
extra = 'forbid'
allow_mutation = True # This allows mutation, cool
validate_assignment = True
underscore_attrs_are_private = True
model: str
_created_at: str = PrivateAttr(default_factory=datetime.utcnow().isoformat)
_is_date_set: bool = PrivateAttr(default_factory=lambda: False)
updated_at: str
version: int = 0
expires: Optional[int] = None
@property
def created_at(self):
return self._created_at
@create_at.setter
def created_at(self, val):
if self._is_date_set:
raise AttributeError('The created_at attribute has already been set')
self._is_date_set = True
self._created_at = x
关于python - Pydantic,允许解析属性或将其传递给构造函数,但使其不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65415197/