Commit e66fe357 authored by Minjong Chung's avatar Minjong Chung Committed by Anssi Kääriäinen
Browse files

Fixed #21102 -- pickling a QuerySet with prefetches twice

Fixed the bug that a QuerySet that prefetches related objects cannot be
pickled and unpickled more than once (The second pickling attempt
raises an exception).

Added a new test for the queryset pickling idempotency.

The bug was introduced by
bac187c0.
parent dbc2e8eb
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -80,10 +80,10 @@ class QuerySet(object):
        if model is None:
            # if model is None, then self should be emptyqs and the related
            # objects do not matter.
            self._known_related_objects = {}
            obj_dict['_known_related_objects'] = {}
        else:
            opts = model._meta
            self._known_related_objects = dict(
            obj_dict['_known_related_objects'] = dict(
                (opts.get_field(field.name if hasattr(field, 'name') else field), val)
                for field, val in obj_dict['_known_related_objects'].items()
            )
+12 −0
Original line number Diff line number Diff line
@@ -73,3 +73,15 @@ class PickleabilityTestCase(TestCase):
        empty = pickle.loads(dumped)
        self.assertQuerysetEqual(
            empty, [])

    def test_pickle_prefetch_related_idempotence(self):
        p = Post.objects.create()
        posts = Post.objects.prefetch_related('materials')

        # First pickling
        posts = pickle.loads(pickle.dumps(posts))
        self.assertQuerysetEqual(posts, [p], lambda x: x)

        # Second pickling
        posts = pickle.loads(pickle.dumps(posts))
        self.assertQuerysetEqual(posts, [p], lambda x: x)