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:
parent
4d654c92ce
commit
f89f1c8acb
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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'),
|
||||||
|
)
|
|
@ -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/')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{% load url from future %}This is where you can find the snark: {% url "snark" %}
|
|
@ -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!')
|
||||||
|
|
Loading…
Reference in New Issue