Pydantic V1
The pydantic documentation desccribes two options that can be used with the .dict() method of models.
- exclude_unset: whether fields which were not explicitly set when creating the model should be excluded from the returned dictionary; default False. Prior to v1.0, exclude_unset was known as skip_defaults; use of skip_defaults is now deprecated
 
- exclude_defaults: whether fields which are equal to their default values (whether set or otherwise) should be excluded from the returned dictionary; default False
 
So you can create a model class with optional fields:
from typing import Optional
from pydantic import BaseModel
class MyModel(BaseModel):
    foo: Optional[int] = None
    bar: Optional[int] = None
And still generate a dict with fields explicitely set to None, but without default values:
baz = MyModel(foo=None)
assert baz.dict(exclude_unset=True) == {"foo": None}
baz = MyModel(bar=None)
assert baz.dict(exclude_unset=True) == {"bar": None}
Pydantic V2
Pydantic V2 is available since June 30, 2023
The .dict() method has been removed in V2. In order to get a dictionary out of a BaseModel instance, one must use the model_dump() method instead:
from __future__ import annotations
from pydantic import BaseModel
class MyModel(BaseModel):
    foo: int | None = None
    bar: int | None = None
baz = MyModel(foo=None)
assert baz.model_dump(exclude_unset=True) == {"foo": None}
baz = MyModel(bar=None)
assert baz.model_dump(exclude_unset=True) == {"bar": None}