diff --git a/django/db/models/base.py b/django/db/models/base.py
index 82283d5..79af1cb 100644
a
|
b
|
from django.db.models.fields.related import (ManyToOneRel,
|
16 | 16 | from django.db import (router, transaction, DatabaseError, |
17 | 17 | DEFAULT_DB_ALIAS) |
18 | 18 | from django.db.models.query import Q |
19 | | from django.db.models.query_utils import DeferredAttribute |
| 19 | from django.db.models.query_utils import DeferredAttribute, deferred_class_factory |
20 | 20 | from django.db.models.deletion import Collector |
21 | 21 | from django.db.models.options import Options |
22 | 22 | from django.db.models import signals |
… |
… |
class Model(object):
|
400 | 400 | need to do things manually, as they're dynamically created classes and |
401 | 401 | only module-level classes can be pickled by the default path. |
402 | 402 | """ |
| 403 | if not self._deferred: |
| 404 | return super(Model, self).__reduce__() |
403 | 405 | data = self.__dict__ |
404 | | model = self.__class__ |
405 | | # The obvious thing to do here is to invoke super().__reduce__() |
406 | | # for the non-deferred case. Don't do that. |
407 | | # On Python 2.4, there is something weird with __reduce__, |
408 | | # and as a result, the super call will cause an infinite recursion. |
409 | | # See #10547 and #12121. |
410 | 406 | defers = [] |
411 | | if self._deferred: |
412 | | from django.db.models.query_utils import deferred_class_factory |
413 | | factory = deferred_class_factory |
414 | | for field in self._meta.fields: |
415 | | if isinstance(self.__class__.__dict__.get(field.attname), |
416 | | DeferredAttribute): |
417 | | defers.append(field.attname) |
418 | | model = self._meta.proxy_for_model |
419 | | else: |
420 | | factory = simple_class_factory |
421 | | return (model_unpickle, (model, defers, factory), data) |
| 407 | for field in self._meta.fields: |
| 408 | if isinstance(self.__class__.__dict__.get(field.attname), |
| 409 | DeferredAttribute): |
| 410 | defers.append(field.attname) |
| 411 | model = self._meta.proxy_for_model |
| 412 | return (model_unpickle, (model, defers), data) |
422 | 413 | |
423 | 414 | def _get_pk_val(self, meta=None): |
424 | 415 | if not meta: |
… |
… |
def get_absolute_url(opts, func, self, *args, **kwargs):
|
926 | 917 | class Empty(object): |
927 | 918 | pass |
928 | 919 | |
929 | | def simple_class_factory(model, attrs): |
930 | | """Used to unpickle Models without deferred fields. |
931 | | |
932 | | We need to do this the hard way, rather than just using |
933 | | the default __reduce__ implementation, because of a |
934 | | __deepcopy__ problem in Python 2.4 |
935 | | """ |
936 | | return model |
937 | | |
938 | | def model_unpickle(model, attrs, factory): |
| 920 | def model_unpickle(model, attrs): |
939 | 921 | """ |
940 | 922 | Used to unpickle Model subclasses with deferred fields. |
941 | 923 | """ |
942 | | cls = factory(model, attrs) |
| 924 | cls = deferred_class_factory(model, attrs) |
943 | 925 | return cls.__new__(cls) |
944 | 926 | model_unpickle.__safe_for_unpickle__ = True |
945 | 927 | |