Ticket #15012: 15012.diff

File 15012.diff, 5.3 KB (added by Joshua "jag" Ginsberg <jag@…>, 13 years ago)

Patch to fix the issue (includes previously attached tests)

  • django/middleware/cache.py

    diff -r 9b484f4bd7e0 django/middleware/cache.py
    a b  
    5050
    5151from django.conf import settings
    5252from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS
     53from django.http import HttpResponse
    5354from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age
    5455
     56def cache_templateresponse_cb(cache_obj, cache_key, timeout):
     57    """Callback for TemplateResponse objects to cache a plain HttpResponse
     58    object upon rendering."""
     59    def __callback__(response):
     60        plain_response = HttpResponse()
     61        for attr in ['status_code', '_headers', '_charset', '_container',
     62                     '_is_string', 'cookies']:
     63            setattr(plain_response, attr, getattr(response, attr))
     64        cache_obj.set(cache_key, plain_response, timeout)
     65        return plain_response
     66    return __callback__
     67
    5568class UpdateCacheMiddleware(object):
    5669    """
    5770    Response-phase cache middleware that updates the cache if the response is
     
    8699        patch_response_headers(response, timeout)
    87100        if timeout:
    88101            cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache)
    89             self.cache.set(cache_key, response, timeout)
     102            if hasattr(response, 'render') and callable(response.render):
     103                response.post_render_callback = cache_templateresponse_cb(
     104                    self.cache, cache_key, timeout)
     105            else:
     106                self.cache.set(cache_key, response, timeout)
    90107        return response
    91108
    92109class FetchFromCacheMiddleware(object):
  • django/template/response.py

    diff -r 9b484f4bd7e0 django/template/response.py
    a b  
    6565        Returns the baked response instance.
    6666        """
    6767        if not self._is_rendered:
     68            if callable(self.pre_render_callback):
     69                self.pre_render_callback(self)
    6870            self._set_content(self.rendered_content)
     71            if callable(self.post_render_callback):
     72                self.post_render_callback(self)
    6973        return self
    7074
    7175    is_rendered = property(lambda self: self._is_rendered)
    7276
     77    pre_render_callback = None
     78    post_render_callback = None
     79
    7380    def __iter__(self):
    7481        if not self._is_rendered:
    7582            raise ContentNotRenderedError('The response content must be rendered before it can be iterated over.')
     
    109116            return context
    110117        else:
    111118            return RequestContext(self._request, context, current_app=self._current_app)
     119
     120   
  • tests/regressiontests/generic_views/base.py

    diff -r 9b484f4bd7e0 tests/regressiontests/generic_views/base.py
    a b  
     1import time
    12import unittest
    23
    34from django.core.exceptions import ImproperlyConfigured
     
    158159    def _assert_about(self, response):
    159160        response.render()
    160161        self.assertEqual(response.status_code, 200)
    161         self.assertEqual(response.content, '<h1>About</h1>')
     162        self.assertContains(response, '<h1>About</h1>')
    162163
    163164    def test_get(self):
    164165        """
     
    197198        self.assertEqual(response.context['params'], {'foo': 'bar'})
    198199        self.assertEqual(response.context['key'], 'value')
    199200
     201    def test_cached_views(self):
     202        """
     203        A template view can be cached
     204        """
     205        response = self.client.get('/template/cached/bar/')
     206        self.assertEqual(response.status_code, 200)
     207
     208        time.sleep(0.2)
     209
     210        response2 = self.client.get('/template/cached/bar/')
     211        self.assertEqual(response2.status_code, 200)
     212
     213        self.assertEqual(response.content, response2.content)
     214
     215        time.sleep(1.0)
     216
     217        # Let the cache expire and test again
     218        response2 = self.client.get('/template/cached/bar/')
     219        self.assertEqual(response2.status_code, 200)
     220
     221        self.assertNotEqual(response.content, response2.content)
     222
    200223class RedirectViewTest(unittest.TestCase):
    201224    rf = RequestFactory()
    202225
  • tests/regressiontests/generic_views/templates/generic_views/about.html

    diff -r 9b484f4bd7e0 tests/regressiontests/generic_views/templates/generic_views/about.html
    a b  
    1 <h1>About</h1>
    2  No newline at end of file
     1<h1>About</h1>
     2{% now "U.u" %}
  • tests/regressiontests/generic_views/urls.py

    diff -r 9b484f4bd7e0 tests/regressiontests/generic_views/urls.py
    a b  
    11from django.conf.urls.defaults import *
    22from django.views.generic import TemplateView
     3from django.views.decorators.cache import cache_page
    34
    45import views
    56
     
    1516    (r'^template/custom/(?P<foo>\w+)/$',
    1617        views.CustomTemplateView.as_view(template_name='generic_views/about.html')),
    1718
     19    (r'^template/cached/(?P<foo>\w+)/$',
     20        cache_page(TemplateView.as_view(template_name='generic_views/about.html'), 1)),
     21
    1822    # DetailView
    1923    (r'^detail/obj/$',
    2024        views.ObjectDetail.as_view()),
Back to Top