3 回答

TA貢獻1772條經驗 獲得超5個贊
您需要validate_assignment在模型配置中啟用選項:
from typing import Optional
from pydantic import BaseModel, validator
class User(BaseModel):
name: Optional[str] = ''
password: Optional[str] = ''
class Config:
validate_assignment = True
@validator('name')
def set_name(cls, name):
return name or 'foo'
user = User(name=None, password='some_password', )
print("Name is ", user.name)
user.name = None
print("Name is ", user.name)
Name is foo
Name is foo

TA貢獻1876條經驗 獲得超7個贊
這個問題問得很好,所以我想提供一個更廣泛的例子,因為有很多方法可以動態分配值。
它僅在字段直接繼承數據類時才有效,更具體地說,這樣的東西是行不通的。
class User(BaseModel):
? ? name: Optional[str] = ""
? ? password: Optional[str] = ""
? ? class Config:
? ? ? ? validate_assignment = True
? ? @validator("name")
? ? def set_name(cls, name):
? ? ? ? return name or "bar"
user_dict = {"password": "so_secret"}
user_one = User(**user_dict)
Out: name='' password='so_secret'
始終驗證
出于性能原因,默認情況下,當未提供值時,不會為字段調用驗證器。但是在這種情況下,當您需要設置動態默認值時,我們可以將其設置為True
class User(BaseModel):
? ? name: Optional[str] = ""
? ? @validator("name", pre=True, always=True)
? ? def set_name(cls, name):
? ? ? ? return name or "bar"
In: user_one = User(name=None)
In: user_two = User()
Out: name='bar'
Out: name='bar'
但是always有一個重要的問題,因為我們使用always=True,pydantic會嘗試驗證默認的None,這會導致錯誤。
將 Pre 設置為True它將在發生驗證錯誤之前調用該字段,驗證器 pre 的默認設置為False,在這種情況下,它們將在字段驗證后調用。
使用配置
但這有一些缺點。
class User(BaseModel):
? ? name: Optional[str] = ""
? ? class Config:
? ? ? ? validate_assignment = True
? ? @validator("name")
? ? def set_name(cls, name):
? ? ? ? return name or "foo"
In:? user = User(name=None)
Out: name='foo'
當您將其設置為 None 時,它會正確返回動態值,但在某些情況下,例如完全返回動態值None,它會失敗。
In:? user = User()
Out: name=''
同樣,您需要進行設置才能使其發揮作用。
pre=True
always=True
使用default_factory
當您想要設置默認值(例如 UUID 或日期時間等)時,這非常有用。在這種情況下,您可能想要使用default_factory,但有一個很大的問題,您無法將Callable參數分配給 default_factory 。
class User(BaseModel):
? ? created_at: datetime = Field(default_factory=datetime.now)
In: user = User()
Out: created_at=datetime.datetime(2020, 8, 29, 2, 40, 12, 780986)

TA貢獻1779條經驗 獲得超6個贊
分配默認值的多種方法
方法#1:id具有默認值的必填字段
class User(BaseModel):
? ? id: str = uuid.uuid4()
方法#2id具有默認值的可選字段
class User(BaseModel):
? ? id: Optional[str] = uuid.uuid4()
方法#3:id具有默認值的必填字段
class User(BaseModel):
? ? id: str = Field(default=uuid.uuid4())
方法#4:具有可id調用默認值的必填字段。這對于生成按需值(例如unique UUIDs或 )非常有用Timestamps。?
class User(BaseModel):
? ? id: str = Field(default_factory=uuid.uuid4)? # uuid.uuid4 is not executed immediately
添加回答
舉報