From 9d83de8ff3b835603fe09e8842529c9810bc1dcd Mon Sep 17 00:00:00 2001 From: Andriy Sokolovskiy Date: Fri, 29 May 2015 14:45:36 +0300 Subject: [PATCH] [1.8.x] Fixed #24831 -- Fixed pickling queryset with prefetch_related() after deleting objects. Backport of 2913d6b77d8b2082dc79df5503b7dd3ddd05fcc1 from master --- django/db/models/fields/related.py | 5 +++++ docs/releases/1.8.3.txt | 3 +++ tests/queryset_pickle/tests.py | 14 ++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 6fa46954e0..ddcf5e3e73 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1407,6 +1407,11 @@ class ManyToOneRel(ForeignObjectRel): parent_link=parent_link, on_delete=on_delete, related_query_name=related_query_name) self.field_name = field_name + def __getstate__(self): + state = self.__dict__.copy() + state.pop('related_model', None) + return state + def get_related_field(self): """ Returns the Field in the 'to' object to which this relationship is diff --git a/docs/releases/1.8.3.txt b/docs/releases/1.8.3.txt index c2a4f6af3d..78e6766872 100644 --- a/docs/releases/1.8.3.txt +++ b/docs/releases/1.8.3.txt @@ -37,3 +37,6 @@ Bugfixes * Fixed lack of unique constraint when changing a field from ``primary_key=True`` to ``unique=True`` (:ticket:`24893`). + +* Fixed queryset pickling when using ``prefetch_related()`` after deleting + objects (:ticket:`24831`). diff --git a/tests/queryset_pickle/tests.py b/tests/queryset_pickle/tests.py index 0125c158af..6a3145e29c 100644 --- a/tests/queryset_pickle/tests.py +++ b/tests/queryset_pickle/tests.py @@ -120,6 +120,20 @@ class PickleabilityTestCase(TestCase): groups = pickle.loads(pickle.dumps(groups)) self.assertQuerysetEqual(groups, [g], lambda x: x) + def test_pickle_prefetch_related_with_m2m_and_objects_deletion(self): + """ + #24831 -- Cached properties on ManyToOneRel created in QuerySet.delete() + caused subsequent QuerySet pickling to fail. + """ + g = Group.objects.create(name='foo') + m2m = M2MModel.objects.create() + m2m.groups.add(g) + Group.objects.all().delete() + + m2ms = M2MModel.objects.prefetch_related('groups') + m2ms = pickle.loads(pickle.dumps(m2ms)) + self.assertQuerysetEqual(m2ms, [m2m], lambda x: x) + def test_missing_django_version_unpickling(self): """ #21430 -- Verifies a warning is raised for querysets that are