users/{uid}/posts or a post’s comments at users/{uid}/posts/{pid}/comments. Firestore Pydantic ODM gives you first-class support for this hierarchy through the Settings.parent attribute, path-aware query methods, and a SubCollectionAccessor convenience wrapper.
Declaring a Subcollection
To declare a subcollection model, add aparent attribute to the model’s inner Settings class and point it at the parent model type. Leave parent unset (or absent) for top-level collections.
How Paths Resolve
The ODM builds the full Firestore path at runtime by walking theSettings.parent chain. Given the models above:
No manual path construction is needed — the ODM calls
_resolve_collection_ref() internally every time a CRUD method is invoked.
Creating Subcollection Documents
Pass the parent instance tosave() when creating a subcollection document. The parent must already have an id (i.e. it must have been saved first).
save(), the ODM stores the resolved parent document path in post._parent_path. Any subsequent update() or delete() call on the same instance no longer requires parent= because the path is already known.
Querying a Subcollection
All read methods accept an optionalparent= argument that scopes the query to the documents under that specific parent document.
find() with a parent
find_one() with a parent
get() by document ID
Updating and Deleting Subcollection Documents
Once an instance has_parent_path set (either from save() or find()), updates and deletes work without a parent= argument.
Cascade Delete
Callingdelete(cascade=True) on a document first recursively deletes all subcollection documents under it, then deletes the document itself. The ODM discovers child models by inspecting _registered_models — every model whose Settings.parent points to the current class is considered a child.
SubCollectionAccessor
SubCollectionAccessor is a convenience wrapper that binds a parent instance to a child model class, giving you a clean object-oriented API for subcollection operations.
Access it via parent_instance.subcollection(ChildModel):
SubCollectionAccessor validates at construction time that ChildModel.Settings.parent matches the type of the parent instance. Passing a mismatched pair raises a ValueError immediately.
Collection Group Queries
A collection group query runs across all subcollections with the same name, regardless of which parent document they live under. Usecollection_group_find() when you need to search data without knowing — or caring about — the parent.
Collection group queries require a composite index in Firestore. If Firestore returns an index error the first time you run a collection group query, follow the link in the error message to create the index in the Firebase console.
_parent_path Tracking
The _parent_path private attribute records the full Firestore document path of the parent (e.g. "users/abc123") on each subcollection instance. It is set automatically in four situations:
- After
save(parent=...)— the resolved parent path is stored on the instance. - After
find(parent=...)orfind_one(parent=...)— every yielded instance has_parent_pathset. - After
get(doc_id, parent=...)— the returned instance has_parent_pathset. - After
collection_group_find()— the parent path is extracted from the document reference path.
_parent_path is stored, you can call update() and delete() on the instance without supplying parent= again:
Full Example
Models
Define Firestore document schemas and configure collection settings.
Database Client
Configure credentials, the emulator, and register your models.
