For example, some model derived from Model class and adds attribute to
model instance that cannot be pickled or just shouldn't be:
{{{
class MyModel(Model):
def __init__(self, *args, **kwargs):
self.service_obj = UnpickleableService() # some service that
shouldn't be pickled, just for example
super().__init__(*args, **kwargs)
}}}
Now it's hard to define that attribute {{{service_obj}}} mustn't be
pickled - what you need to do is define {{{__reduce__}}} method in derived
class and copy third attribute from result of the super method and then
delete {{{service_obj}}} key from that, otherwise you will delete
{{{service_obj}}} from original {{{__dict__}}} attribute:
{{{
class MyModel(Model):
def __init__(self, *args, **kwargs):
self.service_obj = UnpickleableService()
super().__init__(*args, **kwargs)
def __reduce__(self):
callable, args, data = super().__reduce__()
data = data.copy()
del data['service_obj']
return data
}}}
Pickle documentation propose easier way for doing so with defining
{{{__getstate__}}} method that returns object with content that must be
pickled. If that method is absent then {{{__dict__}}} attribute will be
used. With this implementation, Django can define simple
{{{__getstate__}}} method in __Model__ class that will return copy of
{{{__dict__}}} attribute. Developer can define {{{__getstate__}}} method
in derived classes and specify what should or shouldn't be serialized by
pickle in that particular model.
That approach helps to write mixins for models or model hierarchy that
will add some attributes to model instance and exclude them from pickling
results. Also it corresponds to the Pickle documentation.
--
Ticket URL: <https://code.djangoproject.com/ticket/28456>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* owner: nobody => Nerl~
* status: new => assigned
* type: New feature => Cleanup/optimization
--
Ticket URL: <https://code.djangoproject.com/ticket/28456#comment:1>
* stage: Unreviewed => Accepted
Comment:
[https://github.com/django/django/pull/8833 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/28456#comment:2>
Comment (by Chris Adams):
Ran the tests and all worked for me.
--
Ticket URL: <https://code.djangoproject.com/ticket/28456#comment:3>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/28456#comment:4>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"97cb3bd16d8e50d96eb184f8d67dd1723f776d2a" 97cb3bd1]:
{{{
#!CommitTicketReference repository=""
revision="97cb3bd16d8e50d96eb184f8d67dd1723f776d2a"
Fixed #28456 -- Allowed customizing Model pickling by overriding
__getstate__().
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/28456#comment:5>