diff options
Diffstat (limited to 'django/db/models/base.py')
| -rw-r--r-- | django/db/models/base.py | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py index cc03ae1252..29bbde5e6b 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -382,11 +382,18 @@ class ModelBase(type): return cls._meta.default_manager -class ModelStateFieldsCacheDescriptor: +class ModelStateCacheDescriptor: + """ + Upon first access, replace itself with an empty dictionary on the instance. + """ + + def __set_name__(self, owner, name): + self.attribute_name = name + def __get__(self, instance, cls=None): if instance is None: return self - res = instance.fields_cache = {} + res = instance.__dict__[self.attribute_name] = {} return res @@ -398,7 +405,20 @@ class ModelState: # explicit (non-auto) PKs. This impacts validation only; it has no effect # on the actual save. adding = True - fields_cache = ModelStateFieldsCacheDescriptor() + fields_cache = ModelStateCacheDescriptor() + related_managers_cache = ModelStateCacheDescriptor() + + def __getstate__(self): + state = self.__dict__.copy() + if 'fields_cache' in state: + state['fields_cache'] = self.fields_cache.copy() + # Manager instances stored in related_managers_cache won't necessarily + # be deserializable if they were dynamically created via an inner + # scope, e.g. create_forward_many_to_many_manager() and + # create_generic_related_manager(). + if 'related_managers_cache' in state: + state['related_managers_cache'] = {} + return state class Model(metaclass=ModelBase): @@ -552,7 +572,6 @@ class Model(metaclass=ModelBase): """Hook to allow choosing the attributes to pickle.""" state = self.__dict__.copy() state['_state'] = copy.copy(state['_state']) - state['_state'].fields_cache = state['_state'].fields_cache.copy() return state def __setstate__(self, state): |
