diff -r 9b484f4bd7e0 django/middleware/cache.py --- a/django/middleware/cache.py Sat Jan 22 16:16:42 2011 +0000 +++ b/django/middleware/cache.py Sat Jan 22 17:37:43 2011 -0500 @@ -50,8 +50,21 @@ from django.conf import settings from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS +from django.http import HttpResponse from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age +def cache_templateresponse_cb(cache_obj, cache_key, timeout): + """Callback for TemplateResponse objects to cache a plain HttpResponse + object upon rendering.""" + def __callback__(response): + plain_response = HttpResponse() + for attr in ['status_code', '_headers', '_charset', '_container', + '_is_string', 'cookies']: + setattr(plain_response, attr, getattr(response, attr)) + cache_obj.set(cache_key, plain_response, timeout) + return plain_response + return __callback__ + class UpdateCacheMiddleware(object): """ Response-phase cache middleware that updates the cache if the response is @@ -86,7 +99,11 @@ patch_response_headers(response, timeout) if timeout: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) - self.cache.set(cache_key, response, timeout) + if hasattr(response, 'render') and callable(response.render): + response.post_render_callback = cache_templateresponse_cb( + self.cache, cache_key, timeout) + else: + self.cache.set(cache_key, response, timeout) return response class FetchFromCacheMiddleware(object): diff -r 9b484f4bd7e0 django/template/response.py --- a/django/template/response.py Sat Jan 22 16:16:42 2011 +0000 +++ b/django/template/response.py Sat Jan 22 17:37:43 2011 -0500 @@ -65,11 +65,18 @@ Returns the baked response instance. """ if not self._is_rendered: + if callable(self.pre_render_callback): + self.pre_render_callback(self) self._set_content(self.rendered_content) + if callable(self.post_render_callback): + self.post_render_callback(self) return self is_rendered = property(lambda self: self._is_rendered) + pre_render_callback = None + post_render_callback = None + def __iter__(self): if not self._is_rendered: raise ContentNotRenderedError('The response content must be rendered before it can be iterated over.') @@ -109,3 +116,5 @@ return context else: return RequestContext(self._request, context, current_app=self._current_app) + + diff -r 9b484f4bd7e0 tests/regressiontests/generic_views/base.py --- a/tests/regressiontests/generic_views/base.py Sat Jan 22 16:16:42 2011 +0000 +++ b/tests/regressiontests/generic_views/base.py Sat Jan 22 17:37:43 2011 -0500 @@ -1,3 +1,4 @@ +import time import unittest from django.core.exceptions import ImproperlyConfigured @@ -158,7 +159,7 @@ def _assert_about(self, response): response.render() self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, '