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 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)) 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: except http.Http404, e:
logger.warning('Not Found: %s' % request.path, logger.warning('Not Found: %s' % request.path,
extra={ extra={
@ -166,13 +173,6 @@ class BaseHandler(object):
urlresolvers.set_urlconf(None) urlresolvers.set_urlconf(None)
try: 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 # Apply response middleware, regardless of the response
for middleware_method in self._response_middleware: for middleware_method in self._response_middleware:
response = middleware_method(request, response) 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']) self.assert_exceptions_handled('/middleware_exceptions/template_response/', ['Test Template Response Exception'])
# Check that the right middleware methods have been invoked # Check that the right middleware methods have been invoked
self.assert_middleware_usage(pre_middleware, True, True, False, False, False) self.assert_middleware_usage(pre_middleware, True, True, False, True, False)
self.assert_middleware_usage(bad_middleware, True, True, True, False, False) self.assert_middleware_usage(bad_middleware, True, True, True, True, False)
self.assert_middleware_usage(post_middleware, True, True, True, False, False) self.assert_middleware_usage(post_middleware, True, True, True, True, False)
def test_process_response_bad_middleware(self): def test_process_response_bad_middleware(self):
pre_middleware = TestMiddleware() 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 import os
from django.utils import unittest from django.utils import unittest
from django.test import RequestFactory from django.test import RequestFactory, TestCase
from django.conf import settings from django.conf import settings
import django.template.context import django.template.context
from django.template import Template, Context, RequestContext from django.template import Template, Context, RequestContext
@ -11,6 +11,13 @@ def test_processor(request):
return {'processors': 'yes'} return {'processors': 'yes'}
test_processor_name = 'regressiontests.templates.response.test_processor' 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): class BaseTemplateResponseTest(unittest.TestCase):
# tests rely on fact that global context # tests rely on fact that global context
# processors should only work when RequestContext is used. # processors should only work when RequestContext is used.
@ -179,3 +186,23 @@ class TemplateResponseTest(BaseTemplateResponseTest):
rc = response.resolve_context(response.context_data) rc = response.resolve_context(response.context_data)
self.assertEqual(rc.current_app, 'foobar') 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 # Fake views for testing url reverse lookup
from django.http import HttpResponse
from django.template.response import TemplateResponse
def index(request): def index(request):
pass pass
@ -11,3 +14,9 @@ def client_action(request, id, action):
def client2(request, tag): def client2(request, tag):
pass pass
def template_response_view(request):
return TemplateResponse(request, 'response.html', {})
def snark(request):
return HttpResponse('Found him!')