Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added django.middleware.cache, which lets you cache an entire Django-…

…powered site by adding a line to your settings

git-svn-id: http://code.djangoproject.com/svn/django/trunk@178 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 8fd94405b51298e84fea604f339b8147df583270 1 parent 0944653
Adrian Holovaty authored July 18, 2005

Showing 1 changed file with 88 additions and 0 deletions. Show diff stats Hide diff stats

  1. 88  django/middleware/cache.py
88  django/middleware/cache.py
... ...
@@ -0,0 +1,88 @@
  1
+from django.conf import settings
  2
+from django.core.cache import cache
  3
+from django.utils.httpwrappers import HttpResponseNotModified
  4
+from django.utils.text import compress_string
  5
+import datetime, md5
  6
+
  7
+class CacheMiddleware:
  8
+    """
  9
+    Cache middleware. If this is enabled, each Django-powered page will be
  10
+    cached for CACHE_MIDDLEWARE_SECONDS seconds. Cache is based on URLs. Pages
  11
+    with GET or POST parameters are not cached.
  12
+
  13
+    If the cache is shared across multiple sites using the same Django
  14
+    installation, set the CACHE_MIDDLEWARE_KEY_PREFIX to the name of the site,
  15
+    or some other string that is unique to this Django instance, to prevent key
  16
+    collisions.
  17
+
  18
+    This middleware will also make the following optimizations:
  19
+
  20
+    * If the CACHE_MIDDLEWARE_GZIP setting is True, the content will be
  21
+      gzipped.
  22
+
  23
+    * ETags will be added, using a simple MD5 hash of the page's content.
  24
+    """
  25
+    def process_request(self, request):
  26
+        """
  27
+        Checks whether the page is already cached. If it is, returns the cached
  28
+        version. Also handles ETag stuff.
  29
+        """
  30
+        if request.GET or request.POST:
  31
+            request._cache_middleware_set_cache = False
  32
+            return None # Don't bother checking the cache.
  33
+
  34
+        accept_encoding = ''
  35
+        if settings.CACHE_MIDDLEWARE_GZIP:
  36
+            try:
  37
+                accept_encoding = request.META['HTTP_ACCEPT_ENCODING']
  38
+            except KeyError:
  39
+                pass
  40
+        accepts_gzip = 'gzip' in accept_encoding
  41
+        request._cache_middleware_accepts_gzip = accepts_gzip
  42
+
  43
+        # This uses the same cache_key as views.decorators.cache.cache_page,
  44
+        # so the cache can be shared.
  45
+        cache_key = 'views.decorators.cache.cache_page.%s.%s.%s' % \
  46
+            (settings.CACHE_MIDDLEWARE_KEY_PREFIX, request.path, accepts_gzip)
  47
+        request._cache_middleware_key = cache_key
  48
+
  49
+        response = cache.get(cache_key, None)
  50
+        if response is None:
  51
+            request._cache_middleware_set_cache = True
  52
+            return None
  53
+        else:
  54
+            request._cache_middleware_set_cache = False
  55
+            # Logic is from http://simon.incutio.com/archive/2003/04/23/conditionalGet
  56
+            try:
  57
+                if_none_match = request.META['HTTP_IF_NONE_MATCH']
  58
+            except KeyError:
  59
+                if_none_match = None
  60
+            try:
  61
+                if_modified_since = request.META['HTTP_IF_MODIFIED_SINCE']
  62
+            except KeyError:
  63
+                if_modified_since = None
  64
+            if if_none_match is None and if_modified_since is None:
  65
+                pass
  66
+            elif if_none_match is not None and response['ETag'] != if_none_match:
  67
+                pass
  68
+            elif if_modified_since is not None and response['Last-Modified'] != if_modified_since:
  69
+                pass
  70
+            else:
  71
+                return HttpResponseNotModified()
  72
+        return response
  73
+
  74
+    def process_response(self, request, response):
  75
+        """
  76
+        Sets the cache, if needed.
  77
+        """
  78
+        if request._cache_middleware_set_cache:
  79
+            content = response.get_content_as_string('utf-8')
  80
+            if request._cache_middleware_accepts_gzip:
  81
+                content = compress_string(content)
  82
+                response.content = content
  83
+                response['Content-Encoding'] = 'gzip'
  84
+            response['ETag'] = md5.new(content).hexdigest()
  85
+            response['Content-Length'] = '%d' % len(content)
  86
+            response['Last-Modified'] = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
  87
+            cache.set(request._cache_middleware_key, response, settings.CACHE_MIDDLEWARE_SECONDS)
  88
+        return response

0 notes on commit 8fd9440

Please sign in to comment.
Something went wrong with that request. Please try again.