Fixed #8046 -- The first filter() call on a related manager for many-to-many

fields no longer creates duplicate copies of the join table(s). Basically, this
means filters on the join table (for ManyToManyField(through=...)) and complex
filters in the normal (non-through) case don't produce incorrect or duplicate
results.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8472 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-08-22 22:00:28 +00:00
parent 6e36ce1429
commit d4d7bc175d
4 changed files with 80 additions and 43 deletions

View file

@ -121,6 +121,7 @@ class QuerySet(object):
self.query = query or sql.Query(self.model, connection)
self._result_cache = None
self._iter = None
self._sticky_filter = False
########################
# PYTHON MAGIC METHODS #
@ -589,7 +590,10 @@ class QuerySet(object):
def _clone(self, klass=None, setup=False, **kwargs):
if klass is None:
klass = self.__class__
c = klass(model=self.model, query=self.query.clone())
query = self.query.clone()
if self._sticky_filter:
query.filter_is_sticky = True
c = klass(model=self.model, query=query)
c.__dict__.update(kwargs)
if setup and hasattr(c, '_setup_query'):
c._setup_query()
@ -607,6 +611,17 @@ class QuerySet(object):
except StopIteration:
self._iter = None
def _next_is_sticky(self):
"""
Indicates that the next filter call and the one following that should
be treated as a single filter. This is only important when it comes to
determining when to reuse tables for many-to-many filters. Required so
that we can filter naturally on the results of related managers.
"""
obj = self._clone()
obj._sticky_filter = True
return obj
def _merge_sanity_check(self, other):
"""
Checks that we are merging two comparable QuerySet classes. By default