Fixed #15083 -- Corrected the order of TemplateResponse middleware handling, ensuring that custom URLConfs are valid, and that ResponseMiddleware is invoked if the TemplateResponseMiddleware causes errors. Thanks to Sayane for the report.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15226 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2011-01-16 15:38:03 +00:00
parent 4d654c92ce
commit f89f1c8acb
6 changed files with 59 additions and 11 deletions

View File

@ -128,6 +128,13 @@ class BaseHandler(object):
view_name = callback.__class__.__name__ + '.__call__' # If it's a class
raise ValueError("The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name))
# If the response supports deferred rendering, apply template
# response middleware and the render the response
if hasattr(response, 'render') and callable(response.render):
for middleware_method in self._template_response_middleware:
response = middleware_method(request, response)
response.render()
except http.Http404, e:
logger.warning('Not Found: %s' % request.path,
extra={
@ -166,13 +173,6 @@ class BaseHandler(object):
urlresolvers.set_urlconf(None)
try:
# If the response supports deferred rendering, apply template
# response middleware and the render the response
if hasattr(response, 'render') and callable(response.render):
for middleware_method in self._template_response_middleware:
response = middleware_method(request, response)
response.render()
# Apply response middleware, regardless of the response
for middleware_method in self._response_middleware:
response = middleware_method(request, response)

View File

@ -503,9 +503,9 @@ class BadMiddlewareTests(BaseMiddlewareExceptionTest):
self.assert_exceptions_handled('/middleware_exceptions/template_response/', ['Test Template Response Exception'])
# Check that the right middleware methods have been invoked
self.assert_middleware_usage(pre_middleware, True, True, False, False, False)
self.assert_middleware_usage(bad_middleware, True, True, True, False, False)
self.assert_middleware_usage(post_middleware, True, True, True, False, False)
self.assert_middleware_usage(pre_middleware, True, True, False, True, False)
self.assert_middleware_usage(bad_middleware, True, True, True, True, False)
self.assert_middleware_usage(post_middleware, True, True, True, True, False)
def test_process_response_bad_middleware(self):
pre_middleware = TestMiddleware()

View File

@ -0,0 +1,11 @@
# coding: utf-8
from django.conf.urls.defaults import *
from regressiontests.templates import views
urlpatterns = patterns('',
# View returning a template response
(r'^template_response_view/', views.template_response_view),
# A view that can be hard to find...
url(r'^snark/', views.snark, name='snark'),
)

View File

@ -1,6 +1,6 @@
import os
from django.utils import unittest
from django.test import RequestFactory
from django.test import RequestFactory, TestCase
from django.conf import settings
import django.template.context
from django.template import Template, Context, RequestContext
@ -11,6 +11,13 @@ def test_processor(request):
return {'processors': 'yes'}
test_processor_name = 'regressiontests.templates.response.test_processor'
# A test middleware that installs a temporary URLConf
class CustomURLConfMiddleware(object):
def process_request(self, request):
request.urlconf = 'regressiontests.templates.alternate_urls'
class BaseTemplateResponseTest(unittest.TestCase):
# tests rely on fact that global context
# processors should only work when RequestContext is used.
@ -179,3 +186,23 @@ class TemplateResponseTest(BaseTemplateResponseTest):
rc = response.resolve_context(response.context_data)
self.assertEqual(rc.current_app, 'foobar')
class CustomURLConfTest(TestCase):
urls = 'regressiontests.templates.urls'
def setUp(self):
self.old_MIDDLEWARE_CLASSES = settings.MIDDLEWARE_CLASSES
settings.MIDDLEWARE_CLASSES = list(settings.MIDDLEWARE_CLASSES) + [
'regressiontests.templates.response.CustomURLConfMiddleware'
]
def tearDown(self):
settings.MIDDLEWARE_CLASSES = self.old_MIDDLEWARE_CLASSES
def test_custom_urlconf(self):
response = self.client.get('/template_response_view/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, 'This is where you can find the snark: /snark/')

View File

@ -0,0 +1 @@
{% load url from future %}This is where you can find the snark: {% url "snark" %}

View File

@ -1,4 +1,7 @@
# Fake views for testing url reverse lookup
from django.http import HttpResponse
from django.template.response import TemplateResponse
def index(request):
pass
@ -11,3 +14,9 @@ def client_action(request, id, action):
def client2(request, tag):
pass
def template_response_view(request):
return TemplateResponse(request, 'response.html', {})
def snark(request):
return HttpResponse('Found him!')