Pydantic:如果未传递任何值,如何将默认值传递给变量? [英] Pydantic: How to pass the default value to a variable if None was passed?

查看:540
本文介绍了Pydantic:如果未传递任何值,如何将默认值传递给变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果在字段中未输入任何内容,我可以在Pydantic中设置默认值吗?

Can I make a default value in Pydantic if None is passed in the field?

我有以下代码,但在我看来,这里的验证器仅对模型的初始化有效,而对其他模型则无效.

I have the following code, but it seems to me that the validator here only works on initialization of the model and not otherwise.

我的代码:

class User(BaseModel):
     name: Optional[str] = ''
     password: Optional[str] = ''
     email: EmailStr
    

    @validator('name')
    def set_name(cls, name):
        return name or 'foo'

遇到的问题:

user = User(name=None, password='some_password', email='user@example.com')
print("Name is ", user.name)
# > 'Name is foo'

user.name = None
print("Name is ", user.name)
# > 'Name is None'

所需的输出:

user = User(name='some_name', password='some_password', email='user@example.com')
user.name = None
print("Name is ", user.name)
# > 'Name is foo'

关于如何获得所需输出的任何想法?我认为拥有getter和setter方法将有助于解决该问题.但是,我无法让他们在Pydantic模型中工作:

Any ideas on how I can obtain the desired output? I think having getters and setters will help in tackling the issue. However, I could not get them to work in a Pydantic model:

尝试实现getter和setter:

class User(BaseModel):
    name: Optional[str] = ''
    password: Optional[str] = ''
    email: EmailStr

    def get_password(self):
        return self.password

    def set_password(self, password):
        self.password = hash_password(password)

    password = property(get_password, set_password)

user = User(name='some_name', password='some_password', email='user@example.com')
# > RecursionError: maximum recursion depth exceeded

我还尝试了属性装饰器:

class User(BaseModel):
     name: Optional[str] = ''
     password: Optional[str] = ''
     email: EmailStr

    @property
    def password(self):
        return self._password

    @password.setter
    def password(self, password):
        pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
        self._password = pwd_context.hash(password)

user = User(name='some_name', email='user@example.com')
user.password = 'some_password'
# > ValueError: "User" object has no field "password"

我还尝试覆盖 init :

I also tried overwriting the init:

class User(BaseModel):
name: Optional[str] = ""
password: Optional[str] = ""
email: EmailStr

def __init__(self, name, password, email):
    pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
    password = pwd_context.hash(password)
    super().__init__(name=name, password=password, email=email)


user = User(name="some_name", password="some_password", email='user@example.com')
print(user.password)
# > AYylwSnbQgCHrl4uue6kO7yiuT20lazSzK7x # Works as expected

user.password = "some_other_password"
print(user.password)
# > "some_other_password" # Does not work

user.password = None
print(user.password)
# > None # Does not work either

推荐答案

您需要在模型配置中启用 validate_assignment 选项:

You need to enable validate_assignment option in model config:

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

这篇关于Pydantic:如果未传递任何值,如何将默认值传递给变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆