diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2009-11-01 03:06:44 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2009-11-01 03:06:44 +0000 |
| commit | fe9a45e514c93d0b4e5e3ab246e87e1bd7e4d750 (patch) | |
| tree | 0f61030100a812371aa3195cf81d7dc163630471 | |
| parent | 9e02b4a0e13afa1af1c0c7aa8cbe91c7c71eb139 (diff) | |
[1.1.X] Fixed #12121 -- Modified __reduce__ on a model to avoid an infinite recursion problem that occurs on Python 2.4. Thanks to emulbreh for the report.
Backport of r11691 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@11692 bcc190cf-cafb-0310-a4f2-bffc1f526a37
| -rw-r--r-- | django/db/models/base.py | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py index bfe44045f9..edac99d6c9 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -359,20 +359,25 @@ class Model(object): only module-level classes can be pickled by the default path. """ data = self.__dict__ - if not self._deferred: - return super(Model, self).__reduce__() + 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 wierd with __reduce__, + # and as a result, the super call will cause an infinite recursion. + # See #10547 and #12121. defers = [] pk_val = None - for field in self._meta.fields: - if isinstance(self.__class__.__dict__.get(field.attname), - DeferredAttribute): - defers.append(field.attname) - if pk_val is None: - # The pk_val and model values are the same for all - # DeferredAttribute classes, so we only need to do this - # once. - obj = self.__class__.__dict__[field.attname] - model = obj.model_ref() + if self._deferred: + for field in self._meta.fields: + if isinstance(self.__class__.__dict__.get(field.attname), + DeferredAttribute): + defers.append(field.attname) + if pk_val is None: + # The pk_val and model values are the same for all + # DeferredAttribute classes, so we only need to do this + # once. + obj = self.__class__.__dict__[field.attname] + model = obj.model_ref() return (model_unpickle, (model, defers), data) |
