Documentation Index
Fetch the complete documentation index at: https://mintlify.com/santosdevco/firestore-pydantic-odm/llms.txt
Use this file to discover all available pages before exploring further.
FirestoreField is a Python descriptor that sits on each attribute of a BaseFirestoreModel subclass and makes building Firestore query filters feel like ordinary Python comparisons. Instead of writing raw string tuples by hand, you write User.age >= 18 and get back the exact (field_name, operator, value) tuple that find() and find_one() expect — with no string literals that can drift out of sync with your schema.
How it works
FirestoreField implements the descriptor protocol via __get__. The behavior differs depending on whether the attribute is accessed on the class or on an instance:
| Access point | Returns |
|---|---|
User.age (class-level) | The FirestoreField descriptor — enables comparison operators for filter building |
user.age (instance-level) | The actual field value stored on that instance |
Automatic initialization
You never instantiateFirestoreField yourself. When you call init_firestore_odm(), it iterates over every model class you registered and calls model.initialize_fields() on each one. That classmethod walks the Pydantic field definitions and calls setattr(cls, field_name, FirestoreField(alias)) for every field, replacing the default Pydantic descriptor with a FirestoreField descriptor transparently.
The
id field is special: initialize_fields() maps it to FieldPath.document_id() rather than the literal string "id". This ensures equality filters on id are routed through Firestore’s document-ID path, which is required for correct query behaviour on document IDs.String representation
Callingstr() or repr() on a FirestoreField returns the field name (or alias) as a plain string. This lets you pass a descriptor directly to any Firestore API that expects a field path string — for instance in order_by — without any manual coercion.
Comparison operators
Each standard Python comparison operator is overridden to return a(field_name, FirestoreOperators, value) filter tuple instead of a boolean. Pass these tuples — or a list of them — to the filters parameter of find(), find_one(), or count().
| Operator | Generated tuple |
|---|---|
User.age == 30 | ('age', FirestoreOperators.EQ, 30) |
User.age != 30 | ('age', FirestoreOperators.NE, 30) |
User.age < 30 | ('age', FirestoreOperators.LT, 30) |
User.age <= 30 | ('age', FirestoreOperators.LTE, 30) |
User.age > 30 | ('age', FirestoreOperators.GT, 30) |
User.age >= 30 | ('age', FirestoreOperators.GTE, 30) |
Helper methods
Four additional methods cover Firestore operators that have no direct Python operator equivalent.in_(values)
Returns (field_name, FirestoreOperators.IN, values).
Matches documents where the field value is one of the items in values. The list may contain at most 30 elements (Firestore limit).
not_in_(values)
Returns (field_name, FirestoreOperators.NOT_IN, values).
Matches documents where the field value is not in values and the field exists. The list may contain at most 10 elements (Firestore limit).
array_contains(value)
Returns (field_name, FirestoreOperators.ARRAY_CONTAINS, value).
Matches documents where an array field contains the given single value.
array_contains_any(values)
Returns (field_name, FirestoreOperators.ARRAY_CONTAINS_ANY, values).
Matches documents where an array field contains at least one of the values in the list. The list may contain at most 30 elements (Firestore limit).
Complete example
The snippet below shows a realistic query that combines several filter types, ordering, and pagination — all usingFirestoreField descriptors.
