Cheatsheet for Pydantic v2 BaseModel. Long-form: textbook .
Define
from pydantic import BaseModel, EmailStr
from datetime import datetime
class User(BaseModel):
id: int
email: EmailStr
name: str | None = None
created_at: datetime
Validate
# From dict
user = User.model_validate({"id": 1, "email": "[email protected]", "created_at": "2026-01-01T00:00:00Z"})
# From JSON
user = User.model_validate_json('{"id": 1, "email": "[email protected]", ...}')
# Direct
user = User(id=1, email="[email protected]", created_at=datetime.utcnow())
Serialize
user.model_dump() # dict, Python types
user.model_dump(mode="json") # dict, JSON-safe types
user.model_dump_json() # JSON string
user.model_dump(exclude={"created_at"})
user.model_dump(include={"id", "email"})
user.model_dump(exclude_none=True)
user.model_dump(exclude_unset=True)
user.model_dump(by_alias=True)
model_config
class User(BaseModel):
model_config = {
"from_attributes": True, # ORM mode
"populate_by_name": True, # accept both alias and field name
"extra": "forbid", # ignore | allow | forbid
"strict": False, # strict type checking
"frozen": False, # immutable
"validate_assignment": False, # re-validate on attribute set
"use_enum_values": False,
"str_strip_whitespace": False,
"str_to_lower": False,
"arbitrary_types_allowed": False,
"json_schema_extra": {"examples": [...]},
}
Errors
from pydantic import ValidationError
try:
User.model_validate({"id": "abc"})
except ValidationError as e:
print(e.errors())
# [{"type": "int_parsing", "loc": ("id",), "msg": "...", "input": "abc"}, ...]
Each error has type, loc (path), msg, input.
Copy / replace
new_user = user.model_copy(update={"name": "Alice"})
Immutable-style update.
Inheritance
class UserBase(BaseModel):
email: EmailStr
name: str
class UserCreate(UserBase):
password: str
class UserRead(UserBase):
id: int
created_at: datetime
Re-validate on assignment
class User(BaseModel):
model_config = {"validate_assignment": True}
age: int = Field(ge=0)
user = User(age=10)
user.age = -1 # ValidationError
Round-trip JSON
user = User(id=1, email="[email protected]", created_at=datetime.utcnow())
js = user.model_dump_json()
restored = User.model_validate_json(js)
assert restored == user
Common mistakes
Optional[int](works) vsint | None(modern) — pick one.- Defaulting to mutable:
tags: list[str] = []shared across instances; useField(default_factory=list). - Forgetting
from_attributes=Truefor ORM source. - Calling old v1 API:
.dict()→ usemodel_dump().
Read this next
If you want my Pydantic patterns library, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .