Могу ли я сделать значение по умолчанию в Pydantic, если в поле ничего не передается?
У меня есть следующий код, но мне кажется, что здесь валидатор работает только при инициализации модели, а не иначе.
Мой код:
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='[email protected]')
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='[email protected]')
user.name = None
print("Name is ", user.name)
# > 'Name is foo'
Любые идеи о том, как я могу получить желаемый результат? Я думаю, что наличие геттеров и сеттеров поможет в решении этой проблемы. Однако мне не удалось заставить их работать в модели Pydantic:
Попытка реализовать геттеры и сеттеры:
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='[email protected]')
# > 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='[email protected]')
user.password = 'some_password'
# > ValueError: "User" object has no field "password"
Я также пытался перезаписать 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='[email protected]')
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