summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2012-07-07 18:39:09 +0200
committerClaude Paroz <claude@2xlibre.net>2012-07-08 20:08:28 +0200
commit146aff3bac974e56ec8cb597c2720d1cd4f77b26 (patch)
tree1802e3215f2a8fc712b6597bdec7a0119cf401fa
parent1aa0d8ac4d3149fad6ebe80834d9e6f83021cf55 (diff)
Fixed #18590 - Reverted Python 2.4 workaround for Model pickling
Revert of 08d521efa0. Refs #10547, #12121. Thanks Michal Petrucha for the report.
-rw-r--r--django/db/models/base.py40
1 files changed, 11 insertions, 29 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 82283d591c..79af1cb34c 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -16,7 +16,7 @@ from django.db.models.fields.related import (ManyToOneRel,
from django.db import (router, transaction, DatabaseError,
DEFAULT_DB_ALIAS)
from django.db.models.query import Q
-from django.db.models.query_utils import DeferredAttribute
+from django.db.models.query_utils import DeferredAttribute, deferred_class_factory
from django.db.models.deletion import Collector
from django.db.models.options import Options
from django.db.models import signals
@@ -400,25 +400,16 @@ class Model(object):
need to do things manually, as they're dynamically created classes and
only module-level classes can be pickled by the default path.
"""
+ if not self._deferred:
+ return super(Model, self).__reduce__()
data = self.__dict__
- model = self.__class__
- # The obvious thing to do here is to invoke super().__reduce__()
- # for the non-deferred case. Don't do that.
- # On Python 2.4, there is something weird with __reduce__,
- # and as a result, the super call will cause an infinite recursion.
- # See #10547 and #12121.
defers = []
- if self._deferred:
- from django.db.models.query_utils import deferred_class_factory
- factory = deferred_class_factory
- for field in self._meta.fields:
- if isinstance(self.__class__.__dict__.get(field.attname),
- DeferredAttribute):
- defers.append(field.attname)
- model = self._meta.proxy_for_model
- else:
- factory = simple_class_factory
- return (model_unpickle, (model, defers, factory), data)
+ for field in self._meta.fields:
+ if isinstance(self.__class__.__dict__.get(field.attname),
+ DeferredAttribute):
+ defers.append(field.attname)
+ model = self._meta.proxy_for_model
+ return (model_unpickle, (model, defers), data)
def _get_pk_val(self, meta=None):
if not meta:
@@ -926,20 +917,11 @@ def get_absolute_url(opts, func, self, *args, **kwargs):
class Empty(object):
pass
-def simple_class_factory(model, attrs):
- """Used to unpickle Models without deferred fields.
-
- We need to do this the hard way, rather than just using
- the default __reduce__ implementation, because of a
- __deepcopy__ problem in Python 2.4
- """
- return model
-
-def model_unpickle(model, attrs, factory):
+def model_unpickle(model, attrs):
"""
Used to unpickle Model subclasses with deferred fields.
"""
- cls = factory(model, attrs)
+ cls = deferred_class_factory(model, attrs)
return cls.__new__(cls)
model_unpickle.__safe_for_unpickle__ = True