Puis-je faire une valeur par défaut dans PyDantic si aucun n'est transmis dans le champ?
J'ai le code suivant, mais il me semble que le validateur ne fonctionne ici que sur l'initialisation du modèle et non autrement.
Mon code :
class User(BaseModel):
name: Optional[str] = ''
password: Optional[str] = ''
email: EmailStr
@validator('name')
def set_name(cls, name):
return name or 'foo'
Problème rencontré :
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'
sortie souhaitée :
user = User(name='some_name', password='some_password', email='[email protected]')
user.name = None
print("Name is ", user.name)
# > 'Name is foo'
Des idées sur la manière dont je peux obtenir la sortie souhaitée? Je pense avoir des getters et des pigments aidera à résoudre le problème. Cependant, je ne pouvais pas les amener à travailler dans un modèle pydantique:
Tentative d'implémenter des getters and Setters :
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
J'ai également essayé le décorateur de la propriété :
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"
J'ai aussi essayé d'écraser la 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
De nombreuses façons d'attribuer une valeur par défaut
Méthode n ° 1: un champ requis id
avec la valeur par défaut
class User(BaseModel):
id: str = uuid.uuid4()
méthode n ° 2 un champ optionnel id
avec valeur par défaut
class User(BaseModel):
id: Optional[str] = uuid.uuid4()
Méthode n ° 3: un champ requis id
avec valeur par défaut
class User(BaseModel):
id: str = Field(default=uuid.uuid4())
Méthode n ° 4: Un champ requis id
avec la valeur par défaut de l'appelable. Ceci est utile pour générer des valeurs à la demande telles que unique UUIDs
ou Timestamps
. Voir @ Yagiz-degirmenci Réponse.
class User(BaseModel):
id: str = Field(default_factory=uuid.uuid4) # uuid.uuid4 is not executed immediately
Regarder dans l'ajout d'un __init__
Méthode à votre classe. Quelque chose comme
def __init__(self, name, pass, email):
if pass is None:
self.password = "foo"
else:
self.password = pass
self.name = name
self.email = email