Field Validators¶
The --validators option allows you to add custom field validators to generated Pydantic v2 models. This enables you to inject validation logic into generated code without manually editing it.
Basic Usage¶
datamodel-codegen --input schema.json --output model.py \
--validators validators.json \
--output-model-type pydantic_v2.BaseModel
Validators File Format¶
The validators file is a JSON file that maps model names to their validator definitions.
Structure¶
{
"ModelName": {
"validators": [
{
"field": "field_name",
"function": "module.path.to.validator_function",
"mode": "after"
}
]
}
}
Fields¶
| Field | Description | Required |
|---|---|---|
field |
Single field name to validate | One of field or fields |
fields |
List of field names (for multi-field validators) | One of field or fields |
function |
Fully qualified path to the validator function | Yes |
mode |
Validator mode: before, after, wrap, or plain |
No (default: after) |
Validator Modes¶
Pydantic v2 supports different validator modes, each with its own signature:
before / after Mode¶
Standard validators that run before or after Pydantic's own validation:
def validate_name(v: Any, info: ValidationInfo) -> Any:
if not v:
raise ValueError("Name cannot be empty")
return v.strip()
wrap Mode¶
Wrap validators receive a handler to call the next validator in the chain:
from pydantic import ValidationInfo, ValidatorFunctionWrapHandler
def wrap_validate_name(
v: Any,
handler: ValidatorFunctionWrapHandler,
info: ValidationInfo
) -> Any:
# Pre-processing
v = v.strip() if isinstance(v, str) else v
# Call next validator
result = handler(v)
# Post-processing
return result.upper()
plain Mode¶
Plain validators replace Pydantic's validation entirely:
def plain_validate_name(v: Any) -> str:
if not isinstance(v, str):
raise TypeError("Expected string")
return v
Example¶
Input Schema¶
{
"type": "object",
"title": "User",
"properties": {
"name": {"type": "string"},
"email": {"type": "string", "format": "email"},
"age": {"type": "integer", "minimum": 0}
},
"required": ["name", "email"]
}
Validators File¶
{
"User": {
"validators": [
{
"field": "name",
"function": "myapp.validators.validate_name",
"mode": "before"
},
{
"field": "email",
"function": "myapp.validators.validate_email",
"mode": "after"
},
{
"fields": ["name", "email"],
"function": "myapp.validators.validate_contact_info",
"mode": "after"
}
]
}
}
Validator Functions (myapp/validators.py)¶
from typing import Any
from pydantic import ValidationInfo
def validate_name(v: Any, info: ValidationInfo) -> Any:
if isinstance(v, str):
return v.strip()
return v
def validate_email(v: Any, info: ValidationInfo) -> Any:
if isinstance(v, str) and not v.endswith("@example.com"):
# Custom email domain validation
pass
return v
def validate_contact_info(v: Any, info: ValidationInfo) -> Any:
# This runs for both name and email fields
return v
Generated Output¶
from __future__ import annotations
from typing import Any
from myapp.validators import validate_contact_info, validate_email, validate_name
from pydantic import BaseModel, EmailStr, ValidationInfo, conint, field_validator
class User(BaseModel):
name: str
email: EmailStr
age: conint(ge=0) | None = None
@field_validator('name', mode='before')
@classmethod
def validate_name_validator(cls, v: Any, info: ValidationInfo) -> Any:
return validate_name(v, info)
@field_validator('email', mode='after')
@classmethod
def validate_email_validator(cls, v: Any, info: ValidationInfo) -> Any:
return validate_email(v, info)
@field_validator('name', 'email', mode='after')
@classmethod
def validate_contact_info_validator(cls, v: Any, info: ValidationInfo) -> Any:
return validate_contact_info(v, info)
Notes¶
- This feature only supports Pydantic v2 (
--output-model-type pydantic_v2.BaseModel) - The
ModelNamein the validators file must match the generated Python class name - Validator functions are imported automatically based on the
functionpath - When the same validator function is used multiple times, an incrementing suffix (
_1,_2, etc.) is added to ensure method name uniqueness
See Also¶
- CLI Reference:
--validators- CLI option documentation - Pydantic v2 Validators Documentation - Official Pydantic documentation