我想设置默认电子邮件以防未提供电子邮件,即:
name = a
last_name = b
email = None
Run Code Online (Sandbox Code Playgroud)
电子邮件将变为“a_b@email.com”
我尝试了类似的方法,但显然不能用作名称,last_name 未在函数中定义。
class User(BaseModel):
name: Optional[str] = ''
last_name: Optional[str] = ''
email: EmailStr
@validator('email')
def set_email(cls, email):
if not email:
return name + last_name + '@email.com'
else:
return email
Run Code Online (Sandbox Code Playgroud)
更新-仍然不起作用,我尝试过:
@root_validator(pre=True)
def email_set_config(cls, values):
email, name ,last_name = values.get('email'), values.get('name') , values.get('last_name')
if email is None :
email= name + '_' + name + '@' + last_name
return values
Run Code Online (Sandbox Code Playgroud)
解决方案:
添加到类:
- 更新
class Config:
validate_assignment = True
Run Code Online (Sandbox Code Playgroud)
@validator('email')
def set_email(cls, v, values, **kwargs):
return email or values["name"] + '_' + values["name"] + '@' + ["last_name"]
Run Code Online (Sandbox Code Playgroud)
没有足够的声誉来发表评论,所以我将在这里扩展@NobbyNobbs 的答案^^
对于使用 的最后一个示例pydantic.validator,always即使未提供值,您也可以使用 kwargs 始终运行验证器。
文档中的链接:https ://pydantic-docs.helpmanual.io/usage/validators/#validate-always
所以你的例子是:
from typing import Optional
import pydantic
class User(pydantic.BaseModel):
first_name: str
last_name: str
email: Optional[pydantic.EmailStr]
@pydantic.validator('email', always=True)
def set_email(cls, v, values, **kwargs):
return v or values["first_name"] + '_' + values["last_name"] + '@email.com'
if __name__ == "__main__":
print(User(first_name="jon", last_name="doe")) # first_name='jon' last_name='doe' email='jon_doe@email.com'
print(User(first_name="jon", last_name="doe", email=None)) # first_name='jon' last_name='doe' email='jon_doe@email.com'
Run Code Online (Sandbox Code Playgroud)
我对您的模型进行了一些更改,现在它有两个必填字段和一个可选字段,这是根据其他两个字段计算得出的。
from typing import Optional
import pydantic
class User(pydantic.BaseModel):
first_name: str
last_name: str
email: Optional[pydantic.EmailStr]
Run Code Online (Sandbox Code Playgroud)
在实例创建期间验证数据并同时拥有完整模型上下文的第一种方法是使用@pydantic.root_validator:
@pydantic.root_validator
def email_set_config(cls, values):
email, name, last_name = values.get('email'), values.get('first_name'), values.get('last_name')
if email is None:
values["email"] = name + '_' + last_name + '@email.com'
return values
if __name__ == "__main__":
u = User(first_name="jon", last_name="doe")
print(u) # first_name='jon' last_name='doe' email='jon_doe@email.com'
Run Code Online (Sandbox Code Playgroud)
但是如果你只想控制实例化过程,我建议你__init__像这样在模型中重写 dunder
def __init__(__pydantic_self__, **data: Any) -> None:
email, name, last_name = data.get('email'), data.get('first_name'), data.get('last_name')
if email is None:
data["email"] = name + '_' + last_name + '@email.com'
super().__init__(**data)
Run Code Online (Sandbox Code Playgroud)
在我看来,与验证器相比,这是更简单、更直观的方法,我更喜欢它。
您在问题中提到的非根验证器的可能解决方案对我来说有棘手且有点意外的行为。
如果您将命名email参数传递给构造函数,它会像预期的那样工作,但如果没有,则不会。
@pydantic.validator('email')
def set_email(cls, v, values, **kwargs):
return v or values["first_name"] + '_' + values["last_name"] + '@email.com'
if __name__ == "__main__":
print(User(first_name="jon", last_name="doe")) # first_name='jon' last_name='doe' email=None
print(User(first_name="jon", last_name="doe", email=None)) # first_name='jon' last_name='doe' email='jon_doe@email.com'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9112 次 |
| 最近记录: |