Fixed #12876 -- Corrected a problem with recursive relations under deepcopy. Thanks to elachuni for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12700 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2010-03-07 07:11:22 +00:00
parent 5beb5f7372
commit 3508a86ddf
2 changed files with 13 additions and 6 deletions

View File

@ -148,7 +148,7 @@ class Query(object):
return sql % params return sql % params
def __deepcopy__(self, memo): def __deepcopy__(self, memo):
result= self.clone() result = self.clone(memo=memo)
memo[id(self)] = result memo[id(self)] = result
return result return result
@ -199,7 +199,7 @@ class Query(object):
""" """
return self.model._meta return self.model._meta
def clone(self, klass=None, **kwargs): def clone(self, klass=None, memo=None, **kwargs):
""" """
Creates a copy of the current instance. The 'kwargs' parameter can be Creates a copy of the current instance. The 'kwargs' parameter can be
used by clients to update attributes after copying has taken place. used by clients to update attributes after copying has taken place.
@ -223,19 +223,19 @@ class Query(object):
obj.dupe_avoidance = self.dupe_avoidance.copy() obj.dupe_avoidance = self.dupe_avoidance.copy()
obj.select = self.select[:] obj.select = self.select[:]
obj.tables = self.tables[:] obj.tables = self.tables[:]
obj.where = deepcopy(self.where) obj.where = deepcopy(self.where, memo=memo)
obj.where_class = self.where_class obj.where_class = self.where_class
if self.group_by is None: if self.group_by is None:
obj.group_by = None obj.group_by = None
else: else:
obj.group_by = self.group_by[:] obj.group_by = self.group_by[:]
obj.having = deepcopy(self.having) obj.having = deepcopy(self.having, memo=memo)
obj.order_by = self.order_by[:] obj.order_by = self.order_by[:]
obj.low_mark, obj.high_mark = self.low_mark, self.high_mark obj.low_mark, obj.high_mark = self.low_mark, self.high_mark
obj.distinct = self.distinct obj.distinct = self.distinct
obj.select_related = self.select_related obj.select_related = self.select_related
obj.related_select_cols = [] obj.related_select_cols = []
obj.aggregates = deepcopy(self.aggregates) obj.aggregates = deepcopy(self.aggregates, memo=memo)
if self.aggregate_select_mask is None: if self.aggregate_select_mask is None:
obj.aggregate_select_mask = None obj.aggregate_select_mask = None
else: else:
@ -256,7 +256,7 @@ class Query(object):
obj._extra_select_cache = self._extra_select_cache.copy() obj._extra_select_cache = self._extra_select_cache.copy()
obj.extra_tables = self.extra_tables obj.extra_tables = self.extra_tables
obj.extra_order_by = self.extra_order_by obj.extra_order_by = self.extra_order_by
obj.deferred_loading = deepcopy(self.deferred_loading) obj.deferred_loading = deepcopy(self.deferred_loading, memo=memo)
if self.filter_is_sticky and self.used_aliases: if self.filter_is_sticky and self.used_aliases:
obj.used_aliases = self.used_aliases.copy() obj.used_aliases = self.used_aliases.copy()
else: else:

View File

@ -263,6 +263,13 @@ FieldError: Cannot resolve keyword 'reporter_id' into field. Choices are: headli
>>> Reporter.objects.filter(article__reporter__exact=r).distinct() >>> Reporter.objects.filter(article__reporter__exact=r).distinct()
[<Reporter: John Smith>] [<Reporter: John Smith>]
# Regression for #12876 -- Model methods that include queries that
# recursive don't cause recursion depth problems under deepcopy.
>>> r.cached_query = Article.objects.filter(reporter=r)
>>> from copy import deepcopy
>>> deepcopy(r)
<Reporter: John Smith>
# Check that implied __exact also works. # Check that implied __exact also works.
>>> Reporter.objects.filter(article__reporter=r).distinct() >>> Reporter.objects.filter(article__reporter=r).distinct()
[<Reporter: John Smith>] [<Reporter: John Smith>]