Add __reduce__ to MultilingualQuerySet (ref #273).

This commit is contained in:
Jacek Tomaszewski 2014-10-24 19:54:10 +02:00
parent ef8e0b323f
commit 04b67f66d7
2 changed files with 35 additions and 7 deletions

View file

@ -171,6 +171,9 @@ class MultilingualQuerySet(models.query.QuerySet):
ordering.append(rewrite_order_lookup_key(self.model, key))
self.query.add_ordering(*ordering)
def __reduce__(self):
return multilingual_queryset_factory, (self.__class__.__bases__[0],), self.__getstate__()
# This method was not present in django-linguo
def _clone(self, klass=None, *args, **kwargs):
if klass is not None and not issubclass(klass, MultilingualQuerySet):
@ -445,6 +448,16 @@ def get_queryset(obj):
return obj.get_query_set()
def multilingual_queryset_factory(old_cls, instantiate=True):
if old_cls == models.query.QuerySet:
NewClass = MultilingualQuerySet
else:
class NewClass(old_cls, MultilingualQuerySet):
pass
NewClass.__name__ = 'Multilingual%s' % old_cls.__name__
return NewClass() if instantiate else NewClass
class MultilingualQuerysetManager(models.Manager):
"""
This class gets hooked in MRO just before plain Manager, so that every call to
@ -455,13 +468,7 @@ class MultilingualQuerysetManager(models.Manager):
return self._patch_queryset(qs)
def _patch_queryset(self, qs):
if qs.__class__ == models.query.QuerySet:
qs.__class__ = MultilingualQuerySet
else:
class NewClass(qs.__class__, MultilingualQuerySet):
pass
NewClass.__name__ = 'Multilingual%s' % qs.__class__.__name__
qs.__class__ = NewClass
qs.__class__ = multilingual_queryset_factory(qs.__class__, instantiate=False)
qs._post_init()
qs._rewrite_applied_operations()
return qs

View file

@ -2564,6 +2564,27 @@ class TestManager(ModeltranslationTestBase):
qs = models.CustomManagerTestModel.objects.custom_qs()
self.assertIsInstance(qs, MultilingualQuerySet)
def test_multilingual_queryset_pickling(self):
import pickle
from modeltranslation.manager import MultilingualQuerySet
# typical
models.CustomManagerTestModel.objects.create(title='a')
qs = models.CustomManagerTestModel.objects.all()
serialized = pickle.dumps(qs)
deserialized = pickle.loads(serialized)
self.assertIsInstance(deserialized, MultilingualQuerySet)
self.assertListEqual(list(qs), list(deserialized))
# Generated class
models.CustomManager2TestModel.objects.create()
qs = models.CustomManager2TestModel.objects.all()
serialized = pickle.dumps(qs)
deserialized = pickle.loads(serialized)
self.assertIsInstance(deserialized, MultilingualQuerySet)
self.assertIsInstance(deserialized, models.CustomQuerySet)
self.assertListEqual(list(qs), list(deserialized))
def test_non_objects_manager(self):
"""Test if managers other than ``objects`` are patched too"""
from modeltranslation.manager import MultilingualManager