Serialization
Converting models to dicts and JSON with model_dump(), model_dump_json(), exclude, and include.
I know how to create models from data. But how do I get data back out? Like when I need to send a response or save to a database?
Two methods: model_dump() gives you a Python dictionary, and model_dump_json() gives you a JSON string:
from pydantic import BaseModel
class User(BaseModel):
name: str
email: str
age: int
user = User(name="Alice", email="alice@test.com", age=30)
# To dictionary
d = user.model_dump()
print(d) # {'name': 'Alice', 'email': 'alice@test.com', 'age': 30}
# To JSON string
j = user.model_dump_json()
print(j) # '{"name":"Alice","email":"alice@test.com","age":30}'
What if I don't want all the fields in the output? Like I want to exclude the password field from an API response?
Use exclude or include to control which fields appear:
class UserDB(BaseModel):
id: int
name: str
email: str
password_hash: str
user = UserDB(id=1, name="Alice", email="alice@test.com", password_hash="abc123")
# Exclude specific fields
public = user.model_dump(exclude={"password_hash"})
print(public) # {'id': 1, 'name': 'Alice', 'email': 'alice@test.com'}
# Or include only specific fields
brief = user.model_dump(include={"name", "email"})
print(brief) # {'name': 'Alice', 'email': 'alice@test.com'}
Does this work with nested models too? Can I exclude a field from a nested object?
Yes. Use a dictionary to target nested fields:
class Address(BaseModel):
street: str
city: str
zip_code: str
class Customer(BaseModel):
name: str
address: Address
customer = Customer(
name="Alice",
address={"street": "123 Main", "city": "Portland", "zip_code": "97201"}
)
# Exclude zip_code from the nested address
result = customer.model_dump(exclude={"address": {"zip_code"}})
print(result)
# {'name': 'Alice', 'address': {'street': '123 Main', 'city': 'Portland'}}
What about controlling the output format? Like using aliases in the output instead of field names?
Pass by_alias=True to use aliases in the output:
from pydantic import Field
class ApiResponse(BaseModel):
status_code: int = Field(alias="statusCode")
message: str
resp = ApiResponse(statusCode=200, message="OK")
# Default: uses field names
print(resp.model_dump()) # {'status_code': 200, 'message': 'OK'}
# With aliases
print(resp.model_dump(by_alias=True)) # {'statusCode': 200, 'message': 'OK'}
This is the round-trip pattern: data comes in with camelCase aliases, your Python code uses snake_case, and when you serialize back out you switch to aliases again. Clean on both sides.
Is there a way to skip fields that have their default value? Like only include fields that were actually provided?
Use exclude_defaults=True or exclude_unset=True:
class Settings(BaseModel):
theme: str = "light"
font_size: int = 14
language: str = "en"
s = Settings(font_size=18)
print(s.model_dump(exclude_unset=True)) # {'font_size': 18}
exclude_unset=True only includes fields that were explicitly provided. exclude_defaults=True excludes any field whose value equals the default. Both are useful for PATCH-style updates.
Practice your skills
Sign up to write and run code in this lesson.
Serialization
Converting models to dicts and JSON with model_dump(), model_dump_json(), exclude, and include.
I know how to create models from data. But how do I get data back out? Like when I need to send a response or save to a database?
Two methods: model_dump() gives you a Python dictionary, and model_dump_json() gives you a JSON string:
from pydantic import BaseModel
class User(BaseModel):
name: str
email: str
age: int
user = User(name="Alice", email="alice@test.com", age=30)
# To dictionary
d = user.model_dump()
print(d) # {'name': 'Alice', 'email': 'alice@test.com', 'age': 30}
# To JSON string
j = user.model_dump_json()
print(j) # '{"name":"Alice","email":"alice@test.com","age":30}'
What if I don't want all the fields in the output? Like I want to exclude the password field from an API response?
Use exclude or include to control which fields appear:
class UserDB(BaseModel):
id: int
name: str
email: str
password_hash: str
user = UserDB(id=1, name="Alice", email="alice@test.com", password_hash="abc123")
# Exclude specific fields
public = user.model_dump(exclude={"password_hash"})
print(public) # {'id': 1, 'name': 'Alice', 'email': 'alice@test.com'}
# Or include only specific fields
brief = user.model_dump(include={"name", "email"})
print(brief) # {'name': 'Alice', 'email': 'alice@test.com'}
Does this work with nested models too? Can I exclude a field from a nested object?
Yes. Use a dictionary to target nested fields:
class Address(BaseModel):
street: str
city: str
zip_code: str
class Customer(BaseModel):
name: str
address: Address
customer = Customer(
name="Alice",
address={"street": "123 Main", "city": "Portland", "zip_code": "97201"}
)
# Exclude zip_code from the nested address
result = customer.model_dump(exclude={"address": {"zip_code"}})
print(result)
# {'name': 'Alice', 'address': {'street': '123 Main', 'city': 'Portland'}}
What about controlling the output format? Like using aliases in the output instead of field names?
Pass by_alias=True to use aliases in the output:
from pydantic import Field
class ApiResponse(BaseModel):
status_code: int = Field(alias="statusCode")
message: str
resp = ApiResponse(statusCode=200, message="OK")
# Default: uses field names
print(resp.model_dump()) # {'status_code': 200, 'message': 'OK'}
# With aliases
print(resp.model_dump(by_alias=True)) # {'statusCode': 200, 'message': 'OK'}
This is the round-trip pattern: data comes in with camelCase aliases, your Python code uses snake_case, and when you serialize back out you switch to aliases again. Clean on both sides.
Is there a way to skip fields that have their default value? Like only include fields that were actually provided?
Use exclude_defaults=True or exclude_unset=True:
class Settings(BaseModel):
theme: str = "light"
font_size: int = 14
language: str = "en"
s = Settings(font_size=18)
print(s.model_dump(exclude_unset=True)) # {'font_size': 18}
exclude_unset=True only includes fields that were explicitly provided. exclude_defaults=True excludes any field whose value equals the default. Both are useful for PATCH-style updates.
Practice your skills
Sign up to write and run code in this lesson.