示例#1
0
 def _reload(self, key, value):
     """Used by :meth:`~mongoengine.Document.reload` to ensure the
     correct instance is linked to self.
     """
     if isinstance(value, BaseDict):
         value = [(k, self._reload(k, v)) for k, v in list(value.items())]
         value = BaseDict(value, self, key)
     elif isinstance(value, BaseList):
         value = [self._reload(key, v) for v in value]
         value = BaseList(value, self, key)
     elif isinstance(value, (EmbeddedDocument, DynamicEmbeddedDocument)):
         value._changed_fields = []
     return value
示例#2
0
 def _reload(self, key, value):
     """Used by :meth:`~mongoengine.Document.reload` to ensure the
     correct instance is linked to self.
     """
     if isinstance(value, BaseDict):
         value = [(k, self._reload(k, v)) for k, v in list(value.items())]
         value = BaseDict(value, self, key)
     elif isinstance(value, BaseList):
         value = [self._reload(key, v) for v in value]
         value = BaseList(value, self, key)
     elif isinstance(value, (EmbeddedDocument, DynamicEmbeddedDocument)):
         value._instance = None
         value._changed_fields = []
     return value
示例#3
0
    def _attach_objects(self, items, depth=0, instance=None, name=None):
        """
        Recursively finds all db references to be dereferenced

        :param items: The iterable (dict, list, queryset)
        :param depth: The current depth of recursion
        :param instance: The owning instance used for tracking changes by
            :class:`~mongoengine.base.ComplexBaseField`
        :param name: The name of the field, used for tracking changes by
            :class:`~mongoengine.base.ComplexBaseField`
        """
        if not items:
            if isinstance(items, (BaseDict, BaseList)):
                return items

            if instance:
                if isinstance(items, dict):
                    return BaseDict(items, instance, name)
                else:
                    return BaseList(items, instance, name)

        if isinstance(items, (dict, SON)):
            if '_ref' in items:
                return self.object_map.get(
                    (items['_ref'].collection, items['_ref'].id), items)
            elif '_cls' in items:
                doc = get_document(items['_cls'])._from_son(items)
                _cls = doc._data.pop('_cls', None)
                del items['_cls']
                doc._data = self._attach_objects(doc._data, depth, doc, None)
                if _cls is not None:
                    doc._data['_cls'] = _cls
                return doc

        if not hasattr(items, 'items'):
            is_list = True
            list_type = BaseList
            if isinstance(items, EmbeddedDocumentList):
                list_type = EmbeddedDocumentList
            as_tuple = isinstance(items, tuple)
            iterator = enumerate(items)
            data = []
        else:
            is_list = False
            iterator = iter(items.items())
            data = {}

        depth += 1
        for k, v in iterator:
            if is_list:
                data.append(v)
            else:
                data[k] = v

            if k in self.object_map and not is_list:
                data[k] = self.object_map[k]
            elif isinstance(v, (Document, EmbeddedDocument)):
                for field_name in v._fields:
                    v = data[k]._data.get(field_name, None)
                    if isinstance(v, DBRef):
                        data[k]._data[field_name] = self.object_map.get(
                            (v.collection, v.id), v)
                    elif isinstance(v, (dict, SON)) and '_ref' in v:
                        data[k]._data[field_name] = self.object_map.get(
                            (v['_ref'].collection, v['_ref'].id), v)
                    elif isinstance(
                            v,
                        (dict, list, tuple)) and depth <= self.max_depth:
                        item_name = six.text_type('{0}.{1}.{2}').format(
                            name, k, field_name)
                        data[k]._data[field_name] = self._attach_objects(
                            v, depth, instance=instance, name=item_name)
            elif isinstance(v,
                            (dict, list, tuple)) and depth <= self.max_depth:
                item_name = '%s.%s' % (name, k) if name else name
                data[k] = self._attach_objects(v,
                                               depth - 1,
                                               instance=instance,
                                               name=item_name)
            elif hasattr(v, 'id'):
                data[k] = self.object_map.get((v.collection, v.id), v)

        if instance and name:
            if is_list:
                return tuple(data) if as_tuple else list_type(
                    data, instance, name)
            return BaseDict(data, instance, name)
        depth += 1
        return data