From 921e4ccb77ed2056d5cdfc6756ee82b54831937f Mon Sep 17 00:00:00 2001 From: Keryn Knight Date: Mon, 9 Aug 2021 12:28:40 +0100 Subject: [PATCH] Fixed #33003 -- Removed **kwargs from QuerySet._chain(). The functionality of updating the __dict__ was only present to allow for pickling a Prefetch object, which is a comparably rare operation. Forcing the __getstate__() implementation to handle it allows the chaining operation to be slightly faster, which is much more common. --- django/db/models/query.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index 71a52fb754..88cfc3de38 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -1322,7 +1322,7 @@ class QuerySet: self._insert(item, fields=fields, using=self.db, ignore_conflicts=ignore_conflicts) return inserted_rows - def _chain(self, **kwargs): + def _chain(self): """ Return a copy of the current QuerySet that's ready for another operation. @@ -1331,7 +1331,6 @@ class QuerySet: if obj._sticky_filter: obj.query.filter_is_sticky = True obj._sticky_filter = False - obj.__dict__.update(kwargs) return obj def _clone(self): @@ -1622,11 +1621,11 @@ class Prefetch: def __getstate__(self): obj_dict = self.__dict__.copy() if self.queryset is not None: + queryset = self.queryset._chain() # Prevent the QuerySet from being evaluated - obj_dict['queryset'] = self.queryset._chain( - _result_cache=[], - _prefetch_done=True, - ) + queryset._result_cache = [] + queryset._prefetch_done = True + obj_dict['queryset'] = queryset return obj_dict def add_prefix(self, prefix):