Optimised use of 'in' operator on QuerySet using an explicit __contains__ method.
Without this change, use of 'in' on a QuerySet resulted in ._result_cache being fully populated, which sometimes is unnecessary work. git-svn-id: http://code.djangoproject.com/svn/django/trunk@11803 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
bb428f3e86
commit
eeb10d5f2c
|
@ -107,6 +107,36 @@ class QuerySet(object):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def __contains__(self, val):
|
||||||
|
# The 'in' operator works without this method, due to __iter__. This
|
||||||
|
# implementation exists only to shortcut the creation of Model
|
||||||
|
# instances, by bailing out early if we find a matching element.
|
||||||
|
pos = 0
|
||||||
|
if self._result_cache is not None:
|
||||||
|
if val in self._result_cache:
|
||||||
|
return True
|
||||||
|
elif self._iter is None:
|
||||||
|
# iterator is exhausted, so we have our answer
|
||||||
|
return False
|
||||||
|
# remember not to check these again:
|
||||||
|
pos = len(self._result_cache)
|
||||||
|
else:
|
||||||
|
# We need to start filling the result cache out. The following
|
||||||
|
# ensures that self._iter is not None and self._result_cache is not
|
||||||
|
# None
|
||||||
|
it = iter(self)
|
||||||
|
|
||||||
|
# Carry on, one result at a time.
|
||||||
|
while True:
|
||||||
|
if len(self._result_cache) <= pos:
|
||||||
|
self._fill_cache(num=1)
|
||||||
|
if self._iter is None:
|
||||||
|
# we ran out of items
|
||||||
|
return False
|
||||||
|
if self._result_cache[pos] == val:
|
||||||
|
return True
|
||||||
|
pos += 1
|
||||||
|
|
||||||
def __getitem__(self, k):
|
def __getitem__(self, k):
|
||||||
"""
|
"""
|
||||||
Retrieves an item or slice from the set of results.
|
Retrieves an item or slice from the set of results.
|
||||||
|
|
|
@ -211,6 +211,14 @@ True
|
||||||
>>> Article.objects.get(id__exact=8) == Article.objects.get(id__exact=7)
|
>>> Article.objects.get(id__exact=8) == Article.objects.get(id__exact=7)
|
||||||
False
|
False
|
||||||
|
|
||||||
|
# You can use 'in' to test for membership...
|
||||||
|
>>> a8 in Article.objects.all()
|
||||||
|
True
|
||||||
|
|
||||||
|
# ... but there will often be more efficient ways if that is all you need:
|
||||||
|
>>> Article.objects.filter(id=a8.id).exists()
|
||||||
|
True
|
||||||
|
|
||||||
# dates() returns a list of available dates of the given scope for the given field.
|
# dates() returns a list of available dates of the given scope for the given field.
|
||||||
>>> Article.objects.dates('pub_date', 'year')
|
>>> Article.objects.dates('pub_date', 'year')
|
||||||
[datetime.datetime(2005, 1, 1, 0, 0)]
|
[datetime.datetime(2005, 1, 1, 0, 0)]
|
||||||
|
|
Loading…
Reference in New Issue