mirror of
				https://github.com/django/django.git
				synced 2025-11-04 01:47:52 +03:00 
			
		
		
		
	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 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):
 | 
			
		||||
        """
 | 
			
		||||
        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)
 | 
			
		||||
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.
 | 
			
		||||
>>> Article.objects.dates('pub_date', 'year')
 | 
			
		||||
[datetime.datetime(2005, 1, 1, 0, 0)]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user