Ticket #12121: 12121.reduce_deferred.diff
File 12121.reduce_deferred.diff, 3.4 KB (added by , 15 years ago) |
---|
-
django/db/models/base.py
344 344 def __hash__(self): 345 345 return hash(self._get_pk_val()) 346 346 347 def __reduce__(self):348 """349 Provide pickling support. Normally, this just dispatches to Python's350 standard handling. However, for models with deferred field loading, we351 need to do things manually, as they're dynamically created classes and352 only module-level classes can be pickled by the default path.353 """354 data = self.__dict__355 if not self._deferred:356 return super(Model, self).__reduce__()357 defers = []358 pk_val = None359 for field in self._meta.fields:360 if isinstance(self.__class__.__dict__.get(field.attname),361 DeferredAttribute):362 defers.append(field.attname)363 if pk_val is None:364 # The pk_val and model values are the same for all365 # DeferredAttribute classes, so we only need to do this366 # once.367 obj = self.__class__.__dict__[field.attname]368 model = obj.model_ref()369 370 return (model_unpickle, (model, defers), data)371 372 347 def _get_pk_val(self, meta=None): 373 348 if not meta: 374 349 meta = self._meta … … 647 622 class Empty(object): 648 623 pass 649 624 650 def model_unpickle(model, attrs):651 """652 Used to unpickle Model subclasses with deferred fields.653 """654 from django.db.models.query_utils import deferred_class_factory655 cls = deferred_class_factory(model, attrs)656 return cls.__new__(cls)657 model_unpickle.__safe_for_unpickle__ = True658 659 625 if sys.version_info < (2, 5): 660 626 # Prior to Python 2.5, Exception was an old-style class 661 627 def subclass_exception(name, parent, unused): -
django/db/models/query_utils.py
237 237 overrides["Meta"] = Meta 238 238 overrides["__module__"] = model.__module__ 239 239 overrides["_deferred"] = True 240 overrides['__reduce__'] = deferred_model_reduce 240 241 return type(name, (model,), overrides) 242 deferred_class_factory.__safe_for_unpickling__ = True 241 243 242 # The above function is also used to unpickle model instances with deferred 243 # fields. 244 deferred_class_factory.__safe_for_unpickling__ = True 244 def deferred_model_reduce(self): 245 data = self.__dict__ 246 defers = [] 247 pk_val = None 248 for field in self._meta.fields: 249 if isinstance(self.__class__.__dict__.get(field.attname), 250 DeferredAttribute): 251 defers.append(field.attname) 252 if pk_val is None: 253 # The pk_val and model values are the same for all 254 # DeferredAttribute classes, so we only need to do this 255 # once. 256 obj = self.__class__.__dict__[field.attname] 257 model = obj.model_ref() 258 259 return (deferred_model_unpickle, (model, defers), data) 260 261 def deferred_model_unpickle(model, attrs): 262 cls = deferred_class_factory(model, attrs) 263 return cls.__new__(cls) 264 deferred_model_unpickle.__safe_for_unpickle__ = True 265