Complete worked example
python
from typing import Self
from pydantic import BaseModel, Field, ValidationError, model_validator
class Range(BaseModel):
low: int = Field(ge=0)
high: int = Field(ge=0)
@model_validator(mode="after")
def ordered(self) -> Self:
if self.low > self.high:
raise ValueError("low exceeds high")
return self
def inspect_example(payload):
try:
return {"value": Range.model_validate(payload).model_dump()}
except ValidationError as error:
return {"error": sorted({e["type"] for e in error.errors()})}- Reasoning
- An after model validator receives the checked model instance. It compares low and high and returns self when the invariant holds. A failure of an individual Field constraint is reported before this successful-model invariant can be established, which keeps type or lower-bound mistakes separate from the relationship rule. Follow low=2, high=5 through both stages, then compare low=9, high=4. The second mapping passes the local nonnegative checks and fails only the model relationship. The fixture also includes a negative low, demonstrating that the model-level rule does not replace field-local validation.