Skip to content

Instantly share code, notes, and snippets.



Last active Sep 22, 2016
What would you like to do?
Enable pickling of Django QuerySet with abstract intermediate model
import copy_reg
from django.db.models.fields import Field, _load_field, _empty
def _load_field_for_abstract(model, field_name):
return model._meta.get_field(field_name)
def pickle_abstract_field(field):
Pickling should return the model._meta.fields instance of the field,
not a new copy of that field. So, we use the app registry to load the
model and then the field back.
self = field
if not hasattr(self, 'model'):
# Fields are sometimes used without attaching them to models (for
# example in aggregation). In this case give back a plain field
# instance. The code below will create a new empty instance of
# class self.__class__, then update its dict with self.__dict__
# values - so, this is very close to normal pickle.
return _empty, (self.__class__,), self.__dict__
if self.model._deferred:
# Deferred model will not be found from the app registry. This
# could be fixed by reconstructing the deferred model on unpickle.
raise RuntimeError("Fields of deferred models can't be reduced")
if self.model._meta.abstract:
func = _load_field_for_abstract
args = (
func = _load_field
args = (
self.model._meta.app_label, self.model._meta.object_name,
return func, args
copy_reg.pickle(Field, pickle_abstract_field)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment