Ticket #16004: 16004.fix.alternative.2.diff

File 16004.fix.alternative.2.diff, 6.2 KB (added by Luke Plant, 13 years ago)

Fixed issue found by Carl Meyer

  • django/core/handlers/base.py

    diff -r a05dd7353335 django/core/handlers/base.py
    a b  
    133133                if hasattr(response, 'render') and callable(response.render):
    134134                    for middleware_method in self._template_response_middleware:
    135135                        response = middleware_method(request, response)
    136                     response.render()
     136                    response = response.render()
    137137
    138138            except http.Http404, e:
    139139                logger.warning('Not Found: %s' % request.path,
  • django/template/response.py

    diff -r a05dd7353335 django/template/response.py
    a b  
    9292
    9393        Returns the baked response instance.
    9494        """
     95        retval = self
    9596        if not self._is_rendered:
    9697            self._set_content(self.rendered_content)
    9798            for post_callback in self._post_render_callbacks:
    98                 post_callback(self)
    99         return self
     99                newretval = post_callback(retval)
     100                if newretval is not None:
     101                    retval = newretval
     102        return retval
    100103
    101104    is_rendered = property(lambda self: self._is_rendered)
    102105
  • django/utils/decorators.py

    diff -r a05dd7353335 django/utils/decorators.py
    a b  
    9595                        if result is not None:
    9696                            return result
    9797                    raise
    98                 if hasattr(middleware, 'process_response'):
    99                     result = middleware.process_response(request, response)
    100                     if result is not None:
    101                         return result
     98                if hasattr(response, 'render') and callable(response.render):
     99                    if hasattr(middleware, 'process_template_response'):
     100                        response = middleware.process_template_response(request, response)
     101                    # Defer running of process_response, so that we don't
     102                    # force the template to be rendered just yet.
     103                    if hasattr(middleware, 'process_response'):
     104                        callback = lambda response: middleware.process_response(request, response)
     105                        response.add_post_render_callback(callback)
     106                else:
     107                    if hasattr(middleware, 'process_response'):
     108                        return middleware.process_response(request, response)
    102109                return response
    103110            return _wrapped_view
    104111        return _decorator
  • docs/ref/template-response.txt

    diff -r a05dd7353335 docs/ref/template-response.txt
    a b  
    119119    rendered :class:`~django.template.response.SimpleTemplateResponse`
    120120    instance.
    121121
     122    If the callback returns a value that is not `None`, this will be
     123    used as the response instead of the original response object (and
     124    will be passed to the next post rendering callback etc.)
     125
    122126.. method:: SimpleTemplateResponse.render():
    123127
    124128    Sets :attr:`response.content` to the result obtained by
  • tests/regressiontests/utils/decorators.py

    diff -r a05dd7353335 tests/regressiontests/utils/decorators.py
    a b  
    11from django.http import HttpResponse
    22from django.middleware.doc import XViewMiddleware
     3from django.template import Template, Context
     4from django.template.response import TemplateResponse
    35from django.test import TestCase, RequestFactory
    46from django.utils.decorators import decorator_from_middleware
    57
     
    1921class_xview = xview_dec(ClassXView())
    2022
    2123
     24class FullMiddleware(object):
     25    def process_request(self, request):
     26        request.process_request_reached = True
     27
     28    def process_view(sef, request, view_func, view_args, view_kwargs):
     29        request.process_view_reached = True
     30
     31    def process_template_response(self, request, response):
     32        request.process_template_response_reached = True
     33        return response
     34
     35    def process_response(self, request, response):
     36        # This should never receive unrendered content.
     37        request.process_response_content = response.content
     38        request.process_response_reached = True
     39        return response
     40
     41full_dec = decorator_from_middleware(FullMiddleware)
     42
     43
     44def template_response_view(request):
     45    t = Template("Hello world")
     46    return TemplateResponse(request, t, {})
     47
     48decorated_template_response_view = full_dec(template_response_view)
     49
     50def normal_view(request):
     51    t = Template("Hello world")
     52    return HttpResponse(t.render(Context({})))
     53
     54decorated_view = full_dec(normal_view)
     55
    2256class DecoratorFromMiddlewareTests(TestCase):
    2357    """
    2458    Tests for view decorators created using
     
    3771        Test a middleware that implements process_view, operating on a callable class.
    3872        """
    3973        class_xview(self.rf.get('/'))
     74
     75    def test_full_middleware_dec_normal(self):
     76        # Combined tests for all methods are easier
     77        request = self.rf.get('/')
     78        response = decorated_view(request)
     79        self.assertTrue(request.process_request_reached)
     80        self.assertTrue(request.process_view_reached)
     81        self.assertTrue(request.process_response_reached)
     82        self.assertEqual(request.process_response_content, "Hello world")
     83
     84    def test_full_middleware_dec_templateresponse(self):
     85        # Combined tests for all methods are easier
     86        request = self.rf.get('/')
     87        response = decorated_template_response_view(request)
     88        self.assertFalse(response._is_rendered)
     89        response.render()
     90        self.assertTrue(request.process_request_reached)
     91        self.assertTrue(request.process_view_reached)
     92        self.assertTrue(request.process_template_response_reached)
     93        self.assertTrue(request.process_response_reached)
     94        self.assertEqual(request.process_response_content, "Hello world")
Back to Top