Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[1.1.X] Fixed #12163 -- Corrected the unpickling of non-deferred mode…

…ls. Thanks to rfugger for the report and test case.

Backport of r11732 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@11733 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 6ec45f3cb487d5faf50240072bf1440ff336b506 1 parent abd4344
@freakboy3742 freakboy3742 authored
View
21 django/db/models/base.py
@@ -368,6 +368,8 @@ def __reduce__(self):
defers = []
pk_val = None
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):
@@ -378,8 +380,9 @@ def __reduce__(self):
# once.
obj = self.__class__.__dict__[field.attname]
model = obj.model_ref()
-
- return (model_unpickle, (model, defers), data)
+ else:
+ factory = simple_class_factory
+ return (model_unpickle, (model, defers, factory), data)
def _get_pk_val(self, meta=None):
if not meta:
@@ -659,12 +662,20 @@ def get_absolute_url(opts, func, self, *args, **kwargs):
class Empty(object):
pass
-def model_unpickle(model, attrs):
+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):
"""
Used to unpickle Model subclasses with deferred fields.
"""
- from django.db.models.query_utils import deferred_class_factory
- cls = deferred_class_factory(model, attrs)
+ cls = factory(model, attrs)
return cls.__new__(cls)
model_unpickle.__safe_for_unpickle__ = True
View
17 tests/regressiontests/defer_regress/models.py
@@ -115,6 +115,23 @@ def __unicode__(self):
>>> results[0].second_child.name
u'c2'
+# Test for #12163 - Pickling error saving session with unsaved model instances.
+>>> from django.contrib.sessions.backends.db import SessionStore
+>>> SESSION_KEY = '2b1189a188b44ad18c35e1baac6ceead'
+>>> item = Item()
+>>> item._deferred
+False
+>>> s = SessionStore(SESSION_KEY)
+>>> s.clear()
+>>> s['item'] = item
+>>> s.save()
+>>> s = SessionStore(SESSION_KEY)
+>>> s.modified = True
+>>> s.save()
+>>> i2 = s['item']
+>>> i2._deferred # Item must still be non-deferred
+False
+
# Finally, we need to flush the app cache for the defer module.
# Using only/defer creates some artifical entries in the app cache
# that messes up later tests. Purge all entries, just to be sure.
Please sign in to comment.
Something went wrong with that request. Please try again.