Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting a default value based on another value

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?

like image 652
KOB Avatar asked Mar 30 '26 19:03

KOB


1 Answers

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:

  1. 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.

  2. 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.

like image 125
Hernán Alarcón Avatar answered Apr 02 '26 02:04

Hernán Alarcón



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!