Python[Pydantic]-基于类中其他对象的默认值

Python[Pydantic]-基于类中其他对象的默认值,python,pydantic,Python,Pydantic,如果未提供电子邮件,我想设置默认电子邮件, i、 e: 电子邮件将成为“一个_b@email.com" 我试过类似的方法,但显然不能作为名字,姓氏 不在函数中定义 class User(BaseModel): name: Optional[str] = '' last_name: Optional[str] = '' email: EmailStr @validator('email') def set_email(cls, email)

如果未提供电子邮件,我想设置默认电子邮件, i、 e:

电子邮件将成为“一个_b@email.com"

我试过类似的方法,但显然不能作为名字,姓氏 不在函数中定义

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
更新-仍不工作, 我试过:

解决方案:

添加到类中:

--更新

  • 实际上,它在没有定义类配置的情况下工作:

我稍微修改了一下您的模型,现在它有两个必填字段和一个可选字段,这是根据其他两个字段计算的

从输入导入可选
进口pydantic
类用户(pydantic.BaseModel):
名字:str
姓氏:str
电子邮件:可选[pydantic.EmailStr]
在实例创建期间验证数据并同时拥有完整模型上下文的第一种方法是使用
@pydantic.root\u验证器

@pydantic.root\u验证程序
def电子邮件设置配置(cls、值):
email,name,last_name=values.get('email'),values.get('first_name'),values.get('last_name'))
如果电子邮件为无:
值[“email”]=name+''.'+last+'@email.com'
返回值
如果名称=“\uuuuu main\uuuuuuuu”:
u=用户(first_name=“jon”,last_name=“doe”)
打印(u)#第一个#名字class='jon'姓氏class='doe'电子邮件class='jon'_doe@email.com'
但如果您只想控制实例化过程,我建议您在您的模型中像这样重写
\uuuu init\uuuu
dunder

def\uuuu init\uuuu(\uuu pydantic\u self\uuuu,**数据:任意)->无:
email,name,last_name=data.get('email'),data.get('first_name'),data.get('last_name'))
如果电子邮件为无:
数据[“email”]=姓名+''.'+姓氏+'@email.com'
超级()
在我看来,与验证器相比,它更简单、更直观,我更喜欢它

您在讨论中提到的使用非根验证器的可能解决方案,对我来说有一些棘手的、有点出乎意料的行为

如果您将命名的
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'

尝试使用@root_validator@NobbyNobbs-谢谢您的建议,不起作用,更新后。实际上,它起作用了,您不需要在实现中更新值字典,而是设置局部变量。修复它:)@nobbynobs-我明白了,我在帖子中更新了解决方案,你能解释什么时候需要root_验证器吗?nobbynobs,非常感谢你的精彩、详细的解释!学到了一些有用的东西:)
    @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

    class Config:
        validate_assignment = True
    @validator('email')
    def set_email(cls, v, values, **kwargs):
        return email or values["name"] + '_' + values["name"] + '@' + ["last_name"]

    @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'