From 579abf8e660f8209ff8b371f192dac2fe601ad59 Mon Sep 17 00:00:00 2001 From: Carl Meyer Date: Tue, 12 Feb 2013 14:05:31 -0700 Subject: [PATCH] Fix calling create() on a related manager based on PassThroughManager. --- CHANGES.rst | 3 +++ model_utils/managers.py | 3 +++ model_utils/tests/tests.py | 9 +++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3c0feaa..205f651 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,9 @@ CHANGES tip (unreleased) ---------------- +- Fix calling ``create()`` on a ``RelatedManager`` that subclasses a dynamic + ``PassThroughManager``. Thanks SeiryuZ for the report. Fixes GH-24. + - Add workaround for https://code.djangoproject.com/ticket/16855 in InheritanceQuerySet to avoid overriding prior calls to ``select_related()``. Thanks ivirabyan. diff --git a/model_utils/managers.py b/model_utils/managers.py index 6005bf7..74cc7bc 100644 --- a/model_utils/managers.py +++ b/model_utils/managers.py @@ -185,6 +185,9 @@ def create_pass_through_manager_for_queryset_class(base, queryset_cls): return queryset_cls(self.model, **kwargs) def __reduce__(self): + # our pickling support breaks for subclasses (e.g. RelatedManager) + if self.__class__ is not _PassThroughManager: + return super(_PassThroughManager, self).__reduce__() return ( unpickle_pass_through_manager_for_queryset_class, (base, queryset_cls), diff --git a/model_utils/tests/tests.py b/model_utils/tests/tests.py index 4d524cd..20c564d 100644 --- a/model_utils/tests/tests.py +++ b/model_utils/tests/tests.py @@ -608,14 +608,19 @@ class PassThroughManagerTests(TestCase): class CreatePassThroughManagerTests(TestCase): def setUp(self): self.dude = Dude.objects.create(name='El Duderino') - Spot.objects.create(name='The Crib', owner=self.dude, closed=True, - secure=True) def test_reverse_manager(self): + Spot.objects.create( + name='The Crib', owner=self.dude, closed=True, secure=True) self.assertEqual(self.dude.spots_owned.closed().count(), 1) def test_related_queryset_pickling(self): + Spot.objects.create( + name='The Crib', owner=self.dude, closed=True, secure=True) qs = self.dude.spots_owned.closed() pickled_qs = pickle.dumps(qs) unpickled_qs = pickle.loads(pickled_qs) self.assertEqual(unpickled_qs.secured().count(), 1) + + def test_related_manager_create(self): + self.dude.spots_owned.create(name='The Crib', closed=True, secure=True)