Loading django/views/debug.py +34 −19 Original line number Diff line number Diff line Loading @@ -7,12 +7,12 @@ import sys import types from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.urlresolvers import resolve, Resolver404 from django.http import (HttpResponse, HttpResponseNotFound, HttpRequest, build_request_repr) from django.template import Template, Context, TemplateDoesNotExist from django.template import Context, Engine, TemplateDoesNotExist from django.template.defaultfilters import force_escape, pprint from django.template.engine import Engine from django.utils.datastructures import MultiValueDict from django.utils.html import escape from django.utils.encoding import force_bytes, smart_text Loading @@ -21,6 +21,11 @@ from django.utils.module_loading import import_string from django.utils import six from django.utils.translation import ugettext as _ # Minimal Django templates engine to render the error templates # regardless of the project's TEMPLATES setting. DEBUG_ENGINE = Engine(debug=True) HIDDEN_SETTINGS = re.compile('API|TOKEN|KEY|SECRET|PASS|SIGNATURE') CLEANSED_SUBSTITUTE = '********************' Loading Loading @@ -275,19 +280,27 @@ class ExceptionReporter(object): def get_traceback_data(self): """Return a dictionary containing traceback information.""" try: default_template_engine = Engine.get_default() except ImproperlyConfigured: default_template_engine = None # TODO: handle multiple template engines. template_engine = Engine.get_default() # TODO: add support for multiple template engines (#24120). # TemplateDoesNotExist should carry all the information. # Replaying the search process isn't a good design. if self.exc_type and issubclass(self.exc_type, TemplateDoesNotExist): if default_template_engine is None: template_loaders = [] else: self.template_does_not_exist = True self.loader_debug_info = [] # If Django fails in get_template_loaders, provide an empty list # for the following loop to not fail. try: template_loaders = template_engine.template_loaders template_loaders = default_template_engine.template_loaders except Exception: template_loaders = [] for loader in template_loaders: try: source_list_func = loader.get_template_sources Loading @@ -304,8 +317,11 @@ class ExceptionReporter(object): 'loader': loader_name, 'templates': template_list, }) if (template_engine.debug and hasattr(self.exc_value, 'django_template_source')): # TODO: add support for multiple template engines (#24119). if (default_template_engine is not None and default_template_engine.debug and hasattr(self.exc_value, 'django_template_source')): self.get_template_exception_info() frames = self.get_traceback_frames() Loading Loading @@ -362,13 +378,13 @@ class ExceptionReporter(object): def get_traceback_html(self): "Return HTML version of debug 500 HTTP error page." t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template') t = DEBUG_ENGINE.from_string(TECHNICAL_500_TEMPLATE) c = Context(self.get_traceback_data(), use_l10n=False) return t.render(c) def get_traceback_text(self): "Return plain text version of debug 500 HTTP error page." t = Template(TECHNICAL_500_TEXT_TEMPLATE, name='Technical 500 template') t = DEBUG_ENGINE.from_string(TECHNICAL_500_TEXT_TEMPLATE) c = Context(self.get_traceback_data(), autoescape=False, use_l10n=False) return t.render(c) Loading Loading @@ -545,7 +561,7 @@ def technical_404_response(request, exception): module = obj.__module__ caller = '%s.%s' % (module, caller) t = Template(TECHNICAL_404_TEMPLATE, name='Technical 404 template') t = DEBUG_ENGINE.from_string(TECHNICAL_404_TEMPLATE) c = Context({ 'urlconf': urlconf, 'root_urlconf': settings.ROOT_URLCONF, Loading @@ -561,8 +577,7 @@ def technical_404_response(request, exception): def default_urlconf(request): "Create an empty URLconf 404 error response." t = Template(DEFAULT_URLCONF_TEMPLATE, name='Default URLconf template') t = DEBUG_ENGINE.from_string(DEFAULT_URLCONF_TEMPLATE) c = Context({ "title": _("Welcome to Django"), "heading": _("It worked!"), Loading tests/view_tests/tests/test_debug.py +30 −0 Original line number Diff line number Diff line Loading @@ -219,6 +219,36 @@ class DebugViewTests(TestCase): ) @override_settings( DEBUG=True, ROOT_URLCONF="view_tests.urls", # No template directories are configured, so no templates will be found. TEMPLATES=[{ 'BACKEND': 'django.template.backends.dummy.TemplateStrings', }], ) class NonDjangoTemplatesDebugViewTests(TestCase): def test_400(self): # Ensure that when DEBUG=True, technical_500_template() is called. response = self.client.get('/raises400/') self.assertContains(response, '<div class="context" id="', status_code=400) def test_403(self): response = self.client.get('/raises403/') self.assertContains(response, '<h1>403 Forbidden</h1>', status_code=403) def test_404(self): response = self.client.get('/raises404/') self.assertEqual(response.status_code, 404) def test_template_not_found_error(self): # Raises a TemplateDoesNotExist exception and shows the debug view. url = reverse('raises_template_does_not_exist', kwargs={"path": "notfound.html"}) response = self.client.get(url) self.assertContains(response, '<div class="context" id="', status_code=500) class ExceptionReporterTests(TestCase): rf = RequestFactory() Loading Loading
django/views/debug.py +34 −19 Original line number Diff line number Diff line Loading @@ -7,12 +7,12 @@ import sys import types from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.urlresolvers import resolve, Resolver404 from django.http import (HttpResponse, HttpResponseNotFound, HttpRequest, build_request_repr) from django.template import Template, Context, TemplateDoesNotExist from django.template import Context, Engine, TemplateDoesNotExist from django.template.defaultfilters import force_escape, pprint from django.template.engine import Engine from django.utils.datastructures import MultiValueDict from django.utils.html import escape from django.utils.encoding import force_bytes, smart_text Loading @@ -21,6 +21,11 @@ from django.utils.module_loading import import_string from django.utils import six from django.utils.translation import ugettext as _ # Minimal Django templates engine to render the error templates # regardless of the project's TEMPLATES setting. DEBUG_ENGINE = Engine(debug=True) HIDDEN_SETTINGS = re.compile('API|TOKEN|KEY|SECRET|PASS|SIGNATURE') CLEANSED_SUBSTITUTE = '********************' Loading Loading @@ -275,19 +280,27 @@ class ExceptionReporter(object): def get_traceback_data(self): """Return a dictionary containing traceback information.""" try: default_template_engine = Engine.get_default() except ImproperlyConfigured: default_template_engine = None # TODO: handle multiple template engines. template_engine = Engine.get_default() # TODO: add support for multiple template engines (#24120). # TemplateDoesNotExist should carry all the information. # Replaying the search process isn't a good design. if self.exc_type and issubclass(self.exc_type, TemplateDoesNotExist): if default_template_engine is None: template_loaders = [] else: self.template_does_not_exist = True self.loader_debug_info = [] # If Django fails in get_template_loaders, provide an empty list # for the following loop to not fail. try: template_loaders = template_engine.template_loaders template_loaders = default_template_engine.template_loaders except Exception: template_loaders = [] for loader in template_loaders: try: source_list_func = loader.get_template_sources Loading @@ -304,8 +317,11 @@ class ExceptionReporter(object): 'loader': loader_name, 'templates': template_list, }) if (template_engine.debug and hasattr(self.exc_value, 'django_template_source')): # TODO: add support for multiple template engines (#24119). if (default_template_engine is not None and default_template_engine.debug and hasattr(self.exc_value, 'django_template_source')): self.get_template_exception_info() frames = self.get_traceback_frames() Loading Loading @@ -362,13 +378,13 @@ class ExceptionReporter(object): def get_traceback_html(self): "Return HTML version of debug 500 HTTP error page." t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template') t = DEBUG_ENGINE.from_string(TECHNICAL_500_TEMPLATE) c = Context(self.get_traceback_data(), use_l10n=False) return t.render(c) def get_traceback_text(self): "Return plain text version of debug 500 HTTP error page." t = Template(TECHNICAL_500_TEXT_TEMPLATE, name='Technical 500 template') t = DEBUG_ENGINE.from_string(TECHNICAL_500_TEXT_TEMPLATE) c = Context(self.get_traceback_data(), autoescape=False, use_l10n=False) return t.render(c) Loading Loading @@ -545,7 +561,7 @@ def technical_404_response(request, exception): module = obj.__module__ caller = '%s.%s' % (module, caller) t = Template(TECHNICAL_404_TEMPLATE, name='Technical 404 template') t = DEBUG_ENGINE.from_string(TECHNICAL_404_TEMPLATE) c = Context({ 'urlconf': urlconf, 'root_urlconf': settings.ROOT_URLCONF, Loading @@ -561,8 +577,7 @@ def technical_404_response(request, exception): def default_urlconf(request): "Create an empty URLconf 404 error response." t = Template(DEFAULT_URLCONF_TEMPLATE, name='Default URLconf template') t = DEBUG_ENGINE.from_string(DEFAULT_URLCONF_TEMPLATE) c = Context({ "title": _("Welcome to Django"), "heading": _("It worked!"), Loading
tests/view_tests/tests/test_debug.py +30 −0 Original line number Diff line number Diff line Loading @@ -219,6 +219,36 @@ class DebugViewTests(TestCase): ) @override_settings( DEBUG=True, ROOT_URLCONF="view_tests.urls", # No template directories are configured, so no templates will be found. TEMPLATES=[{ 'BACKEND': 'django.template.backends.dummy.TemplateStrings', }], ) class NonDjangoTemplatesDebugViewTests(TestCase): def test_400(self): # Ensure that when DEBUG=True, technical_500_template() is called. response = self.client.get('/raises400/') self.assertContains(response, '<div class="context" id="', status_code=400) def test_403(self): response = self.client.get('/raises403/') self.assertContains(response, '<h1>403 Forbidden</h1>', status_code=403) def test_404(self): response = self.client.get('/raises404/') self.assertEqual(response.status_code, 404) def test_template_not_found_error(self): # Raises a TemplateDoesNotExist exception and shows the debug view. url = reverse('raises_template_does_not_exist', kwargs={"path": "notfound.html"}) response = self.client.get(url) self.assertContains(response, '<div class="context" id="', status_code=500) class ExceptionReporterTests(TestCase): rf = RequestFactory() Loading