Recursively finds all db references to be dereferenced :param items: The iterable (dict, list, queryset) :param depth: The current depth of recursion
(self, items, depth=0)
| 103 | return self._attach_objects(items, 0, instance, name) |
| 104 | |
| 105 | def _find_references(self, items, depth=0): |
| 106 | """ |
| 107 | Recursively finds all db references to be dereferenced |
| 108 | |
| 109 | :param items: The iterable (dict, list, queryset) |
| 110 | :param depth: The current depth of recursion |
| 111 | """ |
| 112 | reference_map = {} |
| 113 | if not items or depth >= self.max_depth: |
| 114 | return reference_map |
| 115 | |
| 116 | # Determine the iterator to use |
| 117 | if isinstance(items, dict): |
| 118 | iterator = items.values() |
| 119 | else: |
| 120 | iterator = items |
| 121 | |
| 122 | # Recursively find dbreferences |
| 123 | depth += 1 |
| 124 | for item in iterator: |
| 125 | if isinstance(item, (Document, EmbeddedDocument)): |
| 126 | for field_name, field in item._fields.items(): |
| 127 | v = item._data.get(field_name, None) |
| 128 | if isinstance(v, LazyReference): |
| 129 | # LazyReference inherits DBRef but should not be dereferenced here ! |
| 130 | continue |
| 131 | elif isinstance(v, DBRef): |
| 132 | reference_map.setdefault(field.document_type, set()).add(v.id) |
| 133 | elif isinstance(v, (dict, SON)) and "_ref" in v: |
| 134 | reference_map.setdefault(get_document(v["_cls"]), set()).add( |
| 135 | v["_ref"].id |
| 136 | ) |
| 137 | elif isinstance(v, (dict, list, tuple)) and depth <= self.max_depth: |
| 138 | field_cls = getattr( |
| 139 | getattr(field, "field", None), "document_type", None |
| 140 | ) |
| 141 | references = self._find_references(v, depth) |
| 142 | for key, refs in references.items(): |
| 143 | if isinstance( |
| 144 | field_cls, (Document, TopLevelDocumentMetaclass) |
| 145 | ): |
| 146 | key = field_cls |
| 147 | reference_map.setdefault(key, set()).update(refs) |
| 148 | elif isinstance(item, LazyReference): |
| 149 | # LazyReference inherits DBRef but should not be dereferenced here ! |
| 150 | continue |
| 151 | elif isinstance(item, DBRef): |
| 152 | reference_map.setdefault(item.collection, set()).add(item.id) |
| 153 | elif isinstance(item, (dict, SON)) and "_ref" in item: |
| 154 | reference_map.setdefault(get_document(item["_cls"]), set()).add( |
| 155 | item["_ref"].id |
| 156 | ) |
| 157 | elif isinstance(item, (dict, list, tuple)) and depth - 1 <= self.max_depth: |
| 158 | references = self._find_references(item, depth - 1) |
| 159 | for key, refs in references.items(): |
| 160 | reference_map.setdefault(key, set()).update(refs) |
| 161 | |
| 162 | return reference_map |
no test coverage detected