python

Django缓存中间件解析。

2017-12-30  本文已影响14人  LumiaXu

前言

如果使用缓存中间件(在settings里面加上设置)那么中间件将会基于URL对Django的页面进行缓存。启用缓存中间件的规范方法是设置“UpdateCacheMiddleware”作为你的第一件中间件,而且“FetchFromCacheMiddleware”作为最后的中间件。
就像下面一样:

MIDDLEWARE = [
        'django.middleware.cache.UpdateCacheMiddleware',
        ...
        'django.middleware.cache.FetchFromCacheMiddleware'
        ]

这是违反直觉的,而违反直觉的原因在于:“UpdateCacheMiddleware” 需要运行最后的响应阶段,处理中间件自下而上; “FetchFromCacheMiddleware” 需要在请求阶段最后运行,自上而下处理中间件。

在缓存中间件中,还有一类简单的中间件:“CacheMiddleware”可以用于一些简单的站点。但是,如果有任何其他中间件需要影响缓存密钥,那么您就可以需要 “UpdateCacheMiddleware” 和 “FetchFromCacheMiddleware”两个中间件,而不是仅用CacheMiddleware一个中间件。这种情况在有“LocaleMiddleware”出现的情况下是尤为经常。

缓存中间件的工作任务:

缓存的代码解析:

中间件

UpdateCacheMiddleware

    def process_response(self, request, response):
        """Sets the cache, if needed."""
        if not self._should_update_cache(request, response):
            # We don't need to update the cache, just return.
            return response

        if response.streaming or response.status_code != 200:
            return response

        # Don't cache responses that set a user-specific (and maybe security
        # sensitive) cookie in response to a cookie-less request.
        if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie'):
            return response

        # Try to get the timeout from the "max-age" section of the "Cache-
        # Control" header before reverting to using the default cache_timeout
        # length.
        timeout = get_max_age(response)
        if timeout is None:
            timeout = self.cache_timeout
        elif timeout == 0:
            # max-age was set to 0, don't bother caching.
            return response
        patch_response_headers(response, timeout)
        if timeout:
            cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache)
            if hasattr(response, 'render') and callable(response.render):
                response.add_post_render_callback(
                    lambda r: self.cache.set(cache_key, r, timeout)
                )
            else:
                self.cache.set(cache_key, response, timeout)
        return response

Hook点:process_response
内容:

FetchFromCacheMiddleware

def process_request(self, request):
        """
        Checks whether the page is already cached and returns the cached
        version if available.
        """
        if request.method not in ('GET', 'HEAD'):
            request._cache_update_cache = False
            return None  # Don't bother checking the cache.

        # try and get the cached GET response
        cache_key = get_cache_key(request, self.key_prefix, 'GET', cache=self.cache)
        if cache_key is None:
            request._cache_update_cache = True
            return None  # No cache information available, need to rebuild.
        response = self.cache.get(cache_key)
        # if it wasn't found and we are looking for a HEAD, try looking just for that
        if response is None and request.method == 'HEAD':
            cache_key = get_cache_key(request, self.key_prefix, 'HEAD', cache=self.cache)
            response = self.cache.get(cache_key)

        if response is None:
            request._cache_update_cache = True
            return None  # No cache information available, need to rebuild.

        # hit, return cached response
        request._cache_update_cache = False
        return response

源码解析:

上一篇下一篇

猜你喜欢

热点阅读