﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
28456	Defining __getstate__ in class derived from Model doesn't affect model pickling	Nerl~	Nerl~	"Current implementation of {{{ Model.__reduce__ }}} does not allow to simply override what attributes should or shouldn't be serialized in classes derived from Model class. [https://docs.python.org/3/library/pickle.html#object.__getstate__ Pickle documentation] says that for that purpose developer can define {{{__getstate__}}} method in class and return dictionary with needed content. That case isn't represented in {{{Model.__reduce__}}} by now, current implementation just using {{{__dict___}}} attribute without copying it so it's difficult to change what attributes must be pickled in derived classes.

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."	Cleanup/optimization	closed	Database layer (models, ORM)	1.11	Normal	fixed	Pickle, Models		Accepted	1	0	0	1	0	0
