Pydantic Basics
9 examples for Pydantic 2 models - 6 basic and 3 intermediate.
Prerequisites
uv pip install "pydantic>=2" pydantic-settings- Pydantic 2 uses pydantic-core for fast validation on Python 3.14.
Basic Examples
1. Define a Model
Typed data container with validation.
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str- BaseModel subclasses define fields.
- Validation runs on instantiation.
- Extra fields forbidden by default in v2 strict modes.
Related: Field Types & Constraints - Field()
2. Validation Errors
Catch bad input.
from pydantic import BaseModel, ValidationError
class Age(BaseModel):
years: int
try:
Age(years="x")
except ValidationError as e:
print(e.error_count())- ValidationError carries locations.
- Use in API 422 responses.
- error_count summarizes failures.
3. Defaults and Optional
Optional fields and factories.
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str
tags: list[str] = Field(default_factory=list)- Use default_factory for mutable defaults.
- Optional means
T | None. - Unset vs explicit null differs in dumps.
4. model_dump
Serialize to dict/JSON-friendly data.
user = User(id=1, name="Ada")
user.model_dump()
user.model_dump(mode="json")- mode='json' converts datetimes.
- exclude_unset omits missing fields.
- Prefer model_dump over dict().
Related: Serialization - advanced dumps
5. Nested Models
Compose structures.
class Address(BaseModel):
city: str
class Profile(BaseModel):
address: Address- Nested models validate recursively.
- Use list[Model] for collections.
- Flatten with model_dump nested.
Related: Nested & Recursive Models - trees
6. ConfigDict
Model-wide behavior.
from pydantic import BaseModel, ConfigDict
class Strict(BaseModel):
model_config = ConfigDict(extra="forbid", str_strip_whitespace=True)- extra='forbid' rejects unknown keys.
- str_strip_whitespace cleans input.
- from_attributes enables ORM mode.
Intermediate Examples
7. field_validator
Field-level custom checks.
from pydantic import BaseModel, field_validator
class EmailUser(BaseModel):
email: str
@field_validator("email")
@classmethod
def must_have_at(cls, v: str) -> str:
if "@" not in v:
raise ValueError("invalid email")
return v.lower()- Validators run after type coercion.
- classmethod required in v2.
- Raise ValueError for failures.
Related: Validators - model validators
8. model_validator
Cross-field rules.
from pydantic import BaseModel, model_validator
class Range(BaseModel):
low: int
high: int
@model_validator(mode="after")
def check_order(self):
if self.high < self.low:
raise ValueError("high < low")
return self- mode='after' sees parsed model.
- Use for password confirm pairs.
- Return self in after validators.
9. JSON Schema
Generate schema for docs.
User.model_json_schema()- Feeds OpenAPI components.
- Keep models as single source of truth.
- Export for client codegen.
Related: Serialization - schema export
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.