def cached(function, key_, duration=DEFAULT_TIMEOUT): """Only calls the function if ``key`` is not already in the cache.""" key = _function_cache_key(key_) val = cache.get(key) if val is None: log.debug('cache miss for %s' % key) val = function() cache.set(key, val, duration) else: log.debug('cache hit for %s' % key) return val
def __iter__(self): if self.iter_function is not None: # This a RawQuerySet. Use the function passed into # the class constructor. iterator = self.iter_function else: # Otherwise, use super().__iter__. iterator = super(CachingModelIterable, self).__iter__ if self.timeout == config.NO_CACHE: # no cache, just iterate and return the results for obj in iterator(): yield obj return # Try to fetch from the cache. try: query_key = self.query_key() except query.EmptyResultSet: return cached = cache.get(query_key) if cached is not None: log.debug('cache hit: %s' % query_key) for obj in cached: obj.from_cache = True yield obj return # Use the special FETCH_BY_ID iterator if configured. if config.FETCH_BY_ID and hasattr(self.queryset, 'fetch_by_id'): iterator = self.queryset.fetch_by_id # No cached results. Do the database query, and cache it once we have # all the objects. to_cache = [] for obj in iterator(): obj.from_cache = False to_cache.append(obj) yield obj if to_cache or config.CACHE_EMPTY_QUERYSETS: self.cache_objects(to_cache, query_key)