7
7
import types
8
8
9
9
from django .conf import settings
10
+ from django .core .exceptions import ImproperlyConfigured
10
11
from django .core .urlresolvers import resolve , Resolver404
11
12
from django .http import (HttpResponse , HttpResponseNotFound , HttpRequest ,
12
13
build_request_repr )
13
- from django .template import Template , Context , TemplateDoesNotExist
14
+ from django .template import Context , Engine , TemplateDoesNotExist
14
15
from django .template .defaultfilters import force_escape , pprint
15
- from django .template .engine import Engine
16
16
from django .utils .datastructures import MultiValueDict
17
17
from django .utils .html import escape
18
18
from django .utils .encoding import force_bytes , smart_text
21
21
from django .utils import six
22
22
from django .utils .translation import ugettext as _
23
23
24
+
25
+ # Minimal Django templates engine to render the error templates
26
+ # regardless of the project's TEMPLATES setting.
27
+ DEBUG_ENGINE = Engine (debug = True )
28
+
24
29
HIDDEN_SETTINGS = re .compile ('API|TOKEN|KEY|SECRET|PASS|SIGNATURE' )
25
30
26
31
CLEANSED_SUBSTITUTE = '********************'
@@ -275,19 +280,27 @@ def format_path_status(self, path):
275
280
276
281
def get_traceback_data (self ):
277
282
"""Return a dictionary containing traceback information."""
283
+ try :
284
+ default_template_engine = Engine .get_default ()
285
+ except ImproperlyConfigured :
286
+ default_template_engine = None
278
287
279
- # TODO: handle multiple template engines.
280
- template_engine = Engine . get_default ()
281
-
288
+ # TODO: add support for multiple template engines (#24120) .
289
+ # TemplateDoesNotExist should carry all the information.
290
+ # Replaying the search process isn't a good design.
282
291
if self .exc_type and issubclass (self .exc_type , TemplateDoesNotExist ):
283
- self .template_does_not_exist = True
284
- self .loader_debug_info = []
285
- # If Django fails in get_template_loaders, provide an empty list
286
- # for the following loop to not fail.
287
- try :
288
- template_loaders = template_engine .template_loaders
289
- except Exception :
292
+ if default_template_engine is None :
290
293
template_loaders = []
294
+ else :
295
+ self .template_does_not_exist = True
296
+ self .loader_debug_info = []
297
+ # If Django fails in get_template_loaders, provide an empty list
298
+ # for the following loop to not fail.
299
+ try :
300
+ template_loaders = default_template_engine .template_loaders
301
+ except Exception :
302
+ template_loaders = []
303
+
291
304
for loader in template_loaders :
292
305
try :
293
306
source_list_func = loader .get_template_sources
@@ -304,8 +317,11 @@ def get_traceback_data(self):
304
317
'loader' : loader_name ,
305
318
'templates' : template_list ,
306
319
})
307
- if (template_engine .debug and
308
- hasattr (self .exc_value , 'django_template_source' )):
320
+
321
+ # TODO: add support for multiple template engines (#24119).
322
+ if (default_template_engine is not None
323
+ and default_template_engine .debug
324
+ and hasattr (self .exc_value , 'django_template_source' )):
309
325
self .get_template_exception_info ()
310
326
311
327
frames = self .get_traceback_frames ()
@@ -362,13 +378,13 @@ def get_traceback_data(self):
362
378
363
379
def get_traceback_html (self ):
364
380
"Return HTML version of debug 500 HTTP error page."
365
- t = Template (TECHNICAL_500_TEMPLATE , name = 'Technical 500 template' )
381
+ t = DEBUG_ENGINE . from_string (TECHNICAL_500_TEMPLATE )
366
382
c = Context (self .get_traceback_data (), use_l10n = False )
367
383
return t .render (c )
368
384
369
385
def get_traceback_text (self ):
370
386
"Return plain text version of debug 500 HTTP error page."
371
- t = Template (TECHNICAL_500_TEXT_TEMPLATE , name = 'Technical 500 template' )
387
+ t = DEBUG_ENGINE . from_string (TECHNICAL_500_TEXT_TEMPLATE )
372
388
c = Context (self .get_traceback_data (), autoescape = False , use_l10n = False )
373
389
return t .render (c )
374
390
@@ -545,7 +561,7 @@ def technical_404_response(request, exception):
545
561
module = obj .__module__
546
562
caller = '%s.%s' % (module , caller )
547
563
548
- t = Template (TECHNICAL_404_TEMPLATE , name = 'Technical 404 template' )
564
+ t = DEBUG_ENGINE . from_string (TECHNICAL_404_TEMPLATE )
549
565
c = Context ({
550
566
'urlconf' : urlconf ,
551
567
'root_urlconf' : settings .ROOT_URLCONF ,
@@ -561,8 +577,7 @@ def technical_404_response(request, exception):
561
577
562
578
def default_urlconf (request ):
563
579
"Create an empty URLconf 404 error response."
564
- t = Template (DEFAULT_URLCONF_TEMPLATE , name = 'Default URLconf template' )
565
-
580
+ t = DEBUG_ENGINE .from_string (DEFAULT_URLCONF_TEMPLATE )
566
581
c = Context ({
567
582
"title" : _ ("Welcome to Django" ),
568
583
"heading" : _ ("It worked!" ),
0 commit comments