I have the following Pydantic model:
from pydantic import BaseModel
import key
class Wallet(BaseModel):
private_key: str = Field(default_factory=key.generate_private_key)
address: str
I want address to have a default_factory as a function that takes a private_key as input and returns an address. My intentions would be something along the lines of the following:
address: str = Field(default_factory=key.generate_address(self.private_key)
How can I achieve this?
Another option is to just use @validator because in it you can access previously validated fields. From the documentation:
- validators are "class methods", so the first argument value they receive is the UserModel class, not an instance of UserModel.
- the second argument is always the field value to validate; it can be named as you please
- you can also add any subset of the following arguments to the signature (the names must match):
values: a dict containing the name-to-value mapping of any previously-validated fields
Example:
class Wallet(BaseModel):
private_key: str = Field(default_factory=key.generate_private_key)
address: str = "" # "" seems better than None to use the correct type
@validator("address", always=True)
def get_address(cls, address: str, values: Dict[str, Any]) -> str:
if address == "" and "private_key" in values:
return key.generate_address(values["private_key"])
return address
It can be argued that @validator should be preferred over @root_validator if you just want to generate a value for a single field.
There are two important aspects of this approach that must be considered:
The "previously-validated fields" from the documentation means that in your case private_key must be defined before address. The values of fields defined after the field that is validated are not available to the validator.
If the field that is validated has a default value and you still want the validator to be executed in that case, you have to use always=True.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With