I want a pydantic Model that can take exactly one of two optional arguments, where the missing argument will be calculated from the other. Consider this: from pydantic import BaseModel, model_validator from typing import Optional class Object: id: int def get_object_by_id(id: int) -> Object: ... class ObjectContent(BaseModel): _object_id: Optional[int] = None _object: Optional[Object] = None @model_validator(mode="before") @classmethod def object_reference(cls, values): if values.get("_object_id") is None and values.get("_object") is None: raise ValueError("Define either _object_id or _object") @property def object_id(self) -> int: if self._object_id is None: self._object_id = self.object.id return self._object_id # type check complains that this might still be None @object_id.setter def object_id(self, id: int): self._object_id = id @property def object(self) -> Object: if self._object is None: self._object = get_object_by_id(self.object_id) return self._object # type check complains that this might still be None @object.setter def object(self, object: Object): self._object = object ObjectContent(_object_id=5) # I would prefer to initialize with the unprotected argument, i.e. ObjectContent(object_id=5) or ObjectContent(object=my_object) I would expecte pydantic to have a more concise solution? Since get_object_from_id would be a costly io-operation it should stay lazy loaded Continue reading...