| @@ -1,3 +1,4 @@ | ||||
| import copy | ||||
| import operator | ||||
| from functools import partial | ||||
|  | ||||
| @@ -461,9 +462,10 @@ class BaseDocument(object): | ||||
|         return cls._meta.get('collection', None) | ||||
|  | ||||
|     @classmethod | ||||
|     def _from_son(cls, son): | ||||
|     def _from_son(cls, son, _auto_dereference=True): | ||||
|         """Create an instance of a Document (subclass) from a PyMongo SON. | ||||
|         """ | ||||
|  | ||||
|         # get the class name from the document, falling back to the given | ||||
|         # class if unavailable | ||||
|         class_name = son.get('_cls', cls._class_name) | ||||
| @@ -480,7 +482,12 @@ class BaseDocument(object): | ||||
|         changed_fields = [] | ||||
|         errors_dict = {} | ||||
|  | ||||
|         for field_name, field in cls._fields.iteritems(): | ||||
|         fields = cls._fields | ||||
|         if not _auto_dereference: | ||||
|             fields = copy.copy(fields) | ||||
|  | ||||
|         for field_name, field in fields.iteritems(): | ||||
|             field._auto_dereference = _auto_dereference | ||||
|             if field.db_field in data: | ||||
|                 value = data[field.db_field] | ||||
|                 try: | ||||
| @@ -507,6 +514,8 @@ class BaseDocument(object): | ||||
|         obj = cls(__auto_convert=False, **data) | ||||
|         obj._changed_fields = changed_fields | ||||
|         obj._created = False | ||||
|         if not _auto_dereference: | ||||
|             obj._fields = fields | ||||
|         return obj | ||||
|  | ||||
|     @classmethod | ||||
|   | ||||
| @@ -168,6 +168,7 @@ class ComplexBaseField(BaseField): | ||||
|                        (self.field is None or isinstance(self.field, | ||||
|                         (GenericReferenceField, ReferenceField)))) | ||||
|  | ||||
|         self._auto_dereference = instance._fields[self.name]._auto_dereference | ||||
|         if not self.__dereference and instance._initialised and dereference: | ||||
|             instance._data[self.name] = self._dereference( | ||||
|                 instance._data.get(self.name), max_depth=1, instance=instance, | ||||
|   | ||||
| @@ -93,7 +93,8 @@ class switch_collection(object): | ||||
| class no_dereference(object): | ||||
|     """ no_dereference context manager. | ||||
|  | ||||
|     Turns off all dereferencing in Documents:: | ||||
|     Turns off all dereferencing in Documents for the duration of the context | ||||
|     manager:: | ||||
|  | ||||
|         with no_dereference(Group) as Group: | ||||
|             Group.objects.find() | ||||
| @@ -118,21 +119,12 @@ class no_dereference(object): | ||||
|  | ||||
|     def __enter__(self): | ||||
|         """ change the objects default and _auto_dereference values""" | ||||
|         if 'queryset_class' in self.cls._meta: | ||||
|             raise OperationError("no_dereference context manager only works on" | ||||
|                                  " default queryset classes") | ||||
|         objects = self.cls.__dict__['objects'] | ||||
|         objects.default = QuerySetNoDeRef | ||||
|         self.cls.objects = objects | ||||
|         for field in self.deref_fields: | ||||
|             self.cls._fields[field]._auto_dereference = False | ||||
|         return self.cls | ||||
|  | ||||
|     def __exit__(self, t, value, traceback): | ||||
|         """ Reset the default and _auto_dereference values""" | ||||
|         objects = self.cls.__dict__['objects'] | ||||
|         objects.default = QuerySet | ||||
|         self.cls.objects = objects | ||||
|         for field in self.deref_fields: | ||||
|             self.cls._fields[field]._auto_dereference = True | ||||
|         return self.cls | ||||
| @@ -145,7 +137,7 @@ class QuerySetNoDeRef(QuerySet): | ||||
|  | ||||
|  | ||||
| class query_counter(object): | ||||
|     """ Query_counter contextmanager to get the number of queries. """ | ||||
|     """ Query_counter context manager to get the number of queries. """ | ||||
|  | ||||
|     def __init__(self): | ||||
|         """ Construct the query_counter. """ | ||||
|   | ||||
| @@ -777,7 +777,7 @@ class ReferenceField(BaseField): | ||||
|  | ||||
|         # Get value from document instance if available | ||||
|         value = instance._data.get(self.name) | ||||
|  | ||||
|         self._auto_dereference = instance._fields[self.name]._auto_dereference | ||||
|         # Dereference DBRefs | ||||
|         if self._auto_dereference and isinstance(value, DBRef): | ||||
|             value = self.document_type._get_db().dereference(value) | ||||
| @@ -859,7 +859,8 @@ class GenericReferenceField(BaseField): | ||||
|             return self | ||||
|  | ||||
|         value = instance._data.get(self.name) | ||||
|         if isinstance(value, (dict, SON)): | ||||
|         self._auto_dereference = instance._fields[self.name]._auto_dereference | ||||
|         if self._auto_dereference and isinstance(value, (dict, SON)): | ||||
|             instance._data[self.name] = self.dereference(value) | ||||
|  | ||||
|         return super(GenericReferenceField, self).__get__(instance, owner) | ||||
|   | ||||
| @@ -42,6 +42,7 @@ class QuerySet(object): | ||||
|     providing :class:`~mongoengine.Document` objects as the results. | ||||
|     """ | ||||
|     __dereference = False | ||||
|     _auto_dereference = True | ||||
|  | ||||
|     def __init__(self, document, collection): | ||||
|         self._document = document | ||||
| @@ -145,10 +146,12 @@ class QuerySet(object): | ||||
|         elif isinstance(key, int): | ||||
|             if queryset._scalar: | ||||
|                 return queryset._get_scalar( | ||||
|                         queryset._document._from_son(queryset._cursor[key])) | ||||
|                         queryset._document._from_son(queryset._cursor[key], | ||||
|                             _auto_dereference=self._auto_dereference)) | ||||
|             if queryset._as_pymongo: | ||||
|                 return queryset._get_as_pymongo(queryset._cursor.next()) | ||||
|             return queryset._document._from_son(queryset._cursor[key]) | ||||
|             return queryset._document._from_son(queryset._cursor[key], | ||||
|                             _auto_dereference=self._auto_dereference) | ||||
|         raise AttributeError | ||||
|  | ||||
|     def __repr__(self): | ||||
| @@ -515,7 +518,7 @@ class QuerySet(object): | ||||
|             '_where_clause', '_loaded_fields', '_ordering', '_snapshot', | ||||
|             '_timeout', '_class_check', '_slave_okay', '_read_preference', | ||||
|             '_iter', '_scalar', '_as_pymongo', '_as_pymongo_coerce', | ||||
|             '_limit', '_skip', '_hint') | ||||
|             '_limit', '_skip', '_hint', '_auto_dereference') | ||||
|  | ||||
|         for prop in copy_props: | ||||
|             val = getattr(self, prop) | ||||
| @@ -1135,6 +1138,12 @@ class QuerySet(object): | ||||
|             self.__dereference = _import_class('DeReference')() | ||||
|         return self.__dereference | ||||
|  | ||||
|     def no_dereference(self): | ||||
|         """Turn off any dereferencing.""" | ||||
|         queryset = self.clone() | ||||
|         queryset._auto_dereference = False | ||||
|         return queryset | ||||
|  | ||||
|     # Helper Functions | ||||
|  | ||||
|     def _item_frequencies_map_reduce(self, field, normalize=False): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user