from django.conf import settings from django.template import Template, Context, TemplateDoesNotExist from django.utils.html import escape from django.http import HttpResponseServerError, HttpResponseNotFound import os, re from itertools import count, izip from os.path import dirname, join as pathjoin HIDDEN_SETTINGS = re.compile('SECRET|PASSWORD') def linebreak_iter(template_source): yield 0 p = template_source.find('\n') while p >= 0: yield p+1 p = template_source.find('\n', p+1) yield len(template_source) + 1 def get_template_exception_info(exc_type, exc_value, tb): origin, (start, end) = exc_value.source template_source = origin.reload() context_lines = 10 line = 0 upto = 0 source_lines = [] before = during = after = "" for num, next in enumerate(linebreak_iter(template_source)): if start >= upto and end <= next: line = num before = escape(template_source[upto:start]) during = escape(template_source[start:end]) after = escape(template_source[end:next]) source_lines.append( (num, escape(template_source[upto:next])) ) upto = next total = len(source_lines) top = max(1, line - context_lines) bottom = min(total, line + 1 + context_lines) template_info = { 'message': exc_value.args[0], 'source_lines': source_lines[top:bottom], 'before': before, 'during': during, 'after': after, 'top': top, 'bottom': bottom, 'total': total, 'line': line, 'name': origin.name, } exc_info = hasattr(exc_value, 'exc_info') and exc_value.exc_info or (exc_type, exc_value, tb) return exc_info + (template_info,) def get_safe_settings(): "Returns a dictionary of the settings module, with sensitive settings blurred out." settings_dict = {} for k in dir(settings): if k.isupper(): if HIDDEN_SETTINGS.search(k): settings_dict[k] = '********************' else: settings_dict[k] = getattr(settings, k) return settings_dict def technical_500_response(request, exc_type, exc_value, tb): """ Create a technical server error response. The last three arguments are the values returned from sys.exc_info() and friends. """ template_info = None template_does_not_exist = False loader_debug_info = None if issubclass(exc_type, TemplateDoesNotExist): from django.template.loader import template_source_loaders template_does_not_exist = True loader_debug_info = [] for loader in template_source_loaders: try: source_list_func = getattr(__import__(loader.__module__, '', '', ['get_template_sources']), 'get_template_sources') # NOTE: This assumes exc_value is the name of the template that # the loader attempted to load. template_list = [{'name': t, 'exists': os.path.exists(t)} \ for t in source_list_func(str(exc_value))] except (ImportError, AttributeError): template_list = [] loader_debug_info.append({ 'loader': loader.__module__ + '.' + loader.__name__, 'templates': template_list, }) if settings.TEMPLATE_DEBUG and hasattr(exc_value, 'source'): exc_type, exc_value, tb, template_info = get_template_exception_info(exc_type, exc_value, tb) frames = [] while tb is not None: filename = tb.tb_frame.f_code.co_filename function = tb.tb_frame.f_code.co_name lineno = tb.tb_lineno - 1 pre_context_lineno, pre_context, context_line, post_context = _get_lines_from_file(filename, lineno, 7) if pre_context_lineno: frames.append({ 'tb': tb, 'filename': filename, 'function': function, 'lineno': lineno + 1, 'vars': tb.tb_frame.f_locals.items(), 'id': id(tb), 'pre_context': pre_context, 'context_line': context_line, 'post_context': post_context, 'pre_context_lineno': pre_context_lineno + 1, }) tb = tb.tb_next t = Template(TECHNICAL_500_TEMPLATE) c = Context({ 'exception_type': exc_type.__name__, 'exception_value': exc_value, 'frames': frames, 'lastframe': frames[-1], 'request': request, 'request_protocol': os.environ.get("HTTPS") == "on" and "https" or "http", 'settings': get_safe_settings(), 'template_info': template_info, 'template_does_not_exist': template_does_not_exist, 'loader_debug_info': loader_debug_info, }) return HttpResponseServerError(t.render(c), mimetype='text/html') def technical_404_response(request, exception): "Create a technical 404 error response. The exception should be the Http404." try: tried = exception.args[0]['tried'] except (IndexError, TypeError): tried = [] else: if not tried: # tried exists but is an empty list. The URLconf must've been empty. return empty_urlconf(request) t = Template(TECHNICAL_404_TEMPLATE) c = Context({ 'root_urlconf': settings.ROOT_URLCONF, 'urlpatterns': tried, 'reason': str(exception), 'request': request, 'request_protocol': os.environ.get("HTTPS") == "on" and "https" or "http", 'settings': get_safe_settings(), }) return HttpResponseNotFound(t.render(c), mimetype='text/html') def empty_urlconf(request): "Create an empty URLconf 404 error response." t = Template(EMPTY_URLCONF_TEMPLATE) c = Context({ 'project_name': settings.SETTINGS_MODULE.split('.')[0] }) return HttpResponseNotFound(t.render(c), mimetype='text/html') def _get_lines_from_file(filename, lineno, context_lines): """ Returns context_lines before and after lineno from file. Returns (pre_context_lineno, pre_context, context_line, post_context). """ try: source = open(filename).readlines() lower_bound = max(0, lineno - context_lines) upper_bound = lineno + context_lines pre_context = [line.strip('\n') for line in source[lower_bound:lineno]] context_line = source[lineno].strip('\n') post_context = [line.strip('\n') for line in source[lineno+1:upper_bound]] return lower_bound, pre_context, context_line, post_context except (OSError, IOError): return None, [], None, [] # # Templates are embedded in the file so that we know the error handler will # always work even if the template loader is broken. # TECHNICAL_500_TEMPLATE = """
Request Method: | {{ request.META.REQUEST_METHOD }} |
---|---|
Request URL: | {{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path }} |
Exception Type: | {{ exception_type }} |
Exception Value: | {{ exception_value }} |
Exception Location: | {{ lastframe.filename }} in {{ lastframe.function }}, line {{ lastframe.lineno }} |
Django tried loading these templates, in this order:
{{ loader.loader }}
:
{{ t.name }}
(File {% if t.exists %}exists{% else %}does not exist{% endif %})Django couldn't find any templates because your TEMPLATE_LOADERS
setting is empty!
In template {{ template_info.name }}
, error at line {{ template_info.line }}
{{ source_line.0 }} | {{ template_info.before }}{{ template_info.during }}{{ template_info.after }} |
---|---|
{{ source_line.0 }} | {{ source_line.1 }} |
{{ frame.filename }}
in {{ frame.function }}
{% if frame.context_line %}
Variable | Value |
---|---|
{{ var.0 }} | {{ var.1|pprint|escape }} |
Traceback (most recent call last):
|
Variable | Value |
---|---|
{{ var.0 }} | {{ var.1|pprint|escape }} |
No GET data
{% endif %}Variable | Value |
---|---|
{{ var.0 }} | {{ var.1|pprint|escape }} |
No POST data
{% endif %}Variable | Value |
---|---|
{{ var.0 }} | {{ var.1|pprint|escape }} |
No cookie data
{% endif %}Variable | Value |
---|---|
{{ var.0 }} | {{ var.1|pprint|escape }} |
{{ settings.SETTINGS_MODULE }}
Setting | Value |
---|---|
{{ var.0 }} | {{ var.1|pprint|escape }} |
You're seeing this error because you have DEBUG = True
in your
Django settings file. Change that to False
, and Django will
display a standard 500 page.
Request Method: | {{ request.META.REQUEST_METHOD }} |
---|---|
Request URL: | {{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path }} |
Using the URLconf defined in {{ settings.ROOT_URLCONF }}
,
Django tried these URL patterns, in this order:
The current URL, {{ request.path }}
, didn't match any of these.
{{ reason|escape }}
{% endif %}
You're seeing this error because you have DEBUG = True
in
your Django settings file. Change that to False
, and Django
will display a standard 404 page.
Of course, you haven't actually done any work yet. Here's what to do next:
DATABASE_*
settings in {{ project_name }}/settings.py
.python {{ project_name }}/manage.py startapp [appname]
.
You're seeing this message because you have DEBUG = True
in your
Django settings file and you haven't configured any URLs. Get to work!