app/django/views/debug.py
changeset 54 03e267d67478
child 323 ff1a9aa48cfd
equal deleted inserted replaced
53:57b4279d8c4e 54:03e267d67478
       
     1 import os
       
     2 import re
       
     3 import sys
       
     4 import datetime
       
     5 
       
     6 from django.conf import settings
       
     7 from django.template import Template, Context, TemplateDoesNotExist
       
     8 from django.utils.html import escape
       
     9 from django.http import HttpResponse, HttpResponseServerError, HttpResponseNotFound
       
    10 from django.utils.encoding import smart_unicode
       
    11 
       
    12 HIDDEN_SETTINGS = re.compile('SECRET|PASSWORD|PROFANITIES_LIST')
       
    13 
       
    14 def linebreak_iter(template_source):
       
    15     yield 0
       
    16     p = template_source.find('\n')
       
    17     while p >= 0:
       
    18         yield p+1
       
    19         p = template_source.find('\n', p+1)
       
    20     yield len(template_source) + 1
       
    21 
       
    22 def get_template_exception_info(exc_type, exc_value, tb):
       
    23     origin, (start, end) = exc_value.source
       
    24     template_source = origin.reload()
       
    25     context_lines = 10
       
    26     line = 0
       
    27     upto = 0
       
    28     source_lines = []
       
    29     before = during = after = ""
       
    30     for num, next in enumerate(linebreak_iter(template_source)):
       
    31         if start >= upto and end <= next:
       
    32             line = num
       
    33             before = escape(template_source[upto:start])
       
    34             during = escape(template_source[start:end])
       
    35             after = escape(template_source[end:next])
       
    36         source_lines.append( (num, escape(template_source[upto:next])) )
       
    37         upto = next
       
    38     total = len(source_lines)
       
    39 
       
    40     top = max(1, line - context_lines)
       
    41     bottom = min(total, line + 1 + context_lines)
       
    42 
       
    43     template_info = {
       
    44         'message': exc_value.args[0],
       
    45         'source_lines': source_lines[top:bottom],
       
    46         'before': before,
       
    47         'during': during,
       
    48         'after': after,
       
    49         'top': top,
       
    50         'bottom': bottom,
       
    51         'total': total,
       
    52         'line': line,
       
    53         'name': origin.name,
       
    54     }
       
    55     exc_info = hasattr(exc_value, 'exc_info') and exc_value.exc_info or (exc_type, exc_value, tb)
       
    56     return exc_info + (template_info,)
       
    57 
       
    58 def get_safe_settings():
       
    59     "Returns a dictionary of the settings module, with sensitive settings blurred out."
       
    60     settings_dict = {}
       
    61     for k in dir(settings):
       
    62         if k.isupper():
       
    63             if HIDDEN_SETTINGS.search(k):
       
    64                 settings_dict[k] = '********************'
       
    65             else:
       
    66                 settings_dict[k] = getattr(settings, k)
       
    67     return settings_dict
       
    68 
       
    69 def technical_500_response(request, exc_type, exc_value, tb):
       
    70     """
       
    71     Create a technical server error response. The last three arguments are
       
    72     the values returned from sys.exc_info() and friends.
       
    73     """
       
    74     html = get_traceback_html(request, exc_type, exc_value, tb)
       
    75     return HttpResponseServerError(html, mimetype='text/html')
       
    76 
       
    77 def get_traceback_html(request, exc_type, exc_value, tb):
       
    78     "Return HTML code for traceback."
       
    79     template_info = None
       
    80     template_does_not_exist = False
       
    81     loader_debug_info = None
       
    82 
       
    83     # Handle deprecated string exceptions
       
    84     if isinstance(exc_type, basestring):
       
    85         exc_value = Exception('Deprecated String Exception: %r' % exc_type)
       
    86         exc_type = type(exc_value)
       
    87 
       
    88     if issubclass(exc_type, TemplateDoesNotExist):
       
    89         from django.template.loader import template_source_loaders
       
    90         template_does_not_exist = True
       
    91         loader_debug_info = []
       
    92         for loader in template_source_loaders:
       
    93             try:
       
    94                 source_list_func = getattr(__import__(loader.__module__, {}, {}, ['get_template_sources']), 'get_template_sources')
       
    95                 # NOTE: This assumes exc_value is the name of the template that
       
    96                 # the loader attempted to load.
       
    97                 template_list = [{'name': t, 'exists': os.path.exists(t)} \
       
    98                     for t in source_list_func(str(exc_value))]
       
    99             except (ImportError, AttributeError):
       
   100                 template_list = []
       
   101             loader_debug_info.append({
       
   102                 'loader': loader.__module__ + '.' + loader.__name__,
       
   103                 'templates': template_list,
       
   104             })
       
   105     if settings.TEMPLATE_DEBUG and hasattr(exc_value, 'source'):
       
   106         exc_type, exc_value, tb, template_info = get_template_exception_info(exc_type, exc_value, tb)
       
   107     frames = []
       
   108     while tb is not None:
       
   109         # support for __traceback_hide__ which is used by a few libraries
       
   110         # to hide internal frames.
       
   111         if tb.tb_frame.f_locals.get('__traceback_hide__'):
       
   112             tb = tb.tb_next
       
   113             continue
       
   114         filename = tb.tb_frame.f_code.co_filename
       
   115         function = tb.tb_frame.f_code.co_name
       
   116         lineno = tb.tb_lineno - 1
       
   117         loader = tb.tb_frame.f_globals.get('__loader__')
       
   118         module_name = tb.tb_frame.f_globals.get('__name__')
       
   119         pre_context_lineno, pre_context, context_line, post_context = _get_lines_from_file(filename, lineno, 7, loader, module_name)
       
   120         if pre_context_lineno is not None:
       
   121             frames.append({
       
   122                 'tb': tb,
       
   123                 'filename': filename,
       
   124                 'function': function,
       
   125                 'lineno': lineno + 1,
       
   126                 'vars': tb.tb_frame.f_locals.items(),
       
   127                 'id': id(tb),
       
   128                 'pre_context': pre_context,
       
   129                 'context_line': context_line,
       
   130                 'post_context': post_context,
       
   131                 'pre_context_lineno': pre_context_lineno + 1,
       
   132             })
       
   133         tb = tb.tb_next
       
   134 
       
   135     if not frames:
       
   136         frames = [{
       
   137             'filename': '&lt;unknown&gt;',
       
   138             'function': '?',
       
   139             'lineno': '?',
       
   140         }]
       
   141 
       
   142     unicode_hint = ''
       
   143     if issubclass(exc_type, UnicodeError):
       
   144         start = getattr(exc_value, 'start', None)
       
   145         end = getattr(exc_value, 'end', None)
       
   146         if start is not None and end is not None:
       
   147             unicode_str = exc_value.args[1]
       
   148             unicode_hint = smart_unicode(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace')
       
   149     from django import get_version
       
   150     t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template')
       
   151     c = Context({
       
   152         'exception_type': exc_type.__name__,
       
   153         'exception_value': smart_unicode(exc_value, errors='replace'),
       
   154         'unicode_hint': unicode_hint,
       
   155         'frames': frames,
       
   156         'lastframe': frames[-1],
       
   157         'request': request,
       
   158         'request_protocol': request.is_secure() and "https" or "http",
       
   159         'settings': get_safe_settings(),
       
   160         'sys_executable': sys.executable,
       
   161         'sys_version_info': '%d.%d.%d' % sys.version_info[0:3],
       
   162         'server_time': datetime.datetime.now(),
       
   163         'django_version_info': get_version(),
       
   164         'sys_path' : sys.path,
       
   165         'template_info': template_info,
       
   166         'template_does_not_exist': template_does_not_exist,
       
   167         'loader_debug_info': loader_debug_info,
       
   168     })
       
   169     return t.render(c)
       
   170 
       
   171 def technical_404_response(request, exception):
       
   172     "Create a technical 404 error response. The exception should be the Http404."
       
   173     try:
       
   174         tried = exception.args[0]['tried']
       
   175     except (IndexError, TypeError):
       
   176         tried = []
       
   177     else:
       
   178         if not tried:
       
   179             # tried exists but is an empty list. The URLconf must've been empty.
       
   180             return empty_urlconf(request)
       
   181 
       
   182     t = Template(TECHNICAL_404_TEMPLATE, name='Technical 404 template')
       
   183     c = Context({
       
   184         'root_urlconf': settings.ROOT_URLCONF,
       
   185         'request_path': request.path[1:], # Trim leading slash
       
   186         'urlpatterns': tried,
       
   187         'reason': str(exception),
       
   188         'request': request,
       
   189         'request_protocol': request.is_secure() and "https" or "http",
       
   190         'settings': get_safe_settings(),
       
   191     })
       
   192     return HttpResponseNotFound(t.render(c), mimetype='text/html')
       
   193 
       
   194 def empty_urlconf(request):
       
   195     "Create an empty URLconf 404 error response."
       
   196     t = Template(EMPTY_URLCONF_TEMPLATE, name='Empty URLConf template')
       
   197     c = Context({
       
   198         'project_name': settings.SETTINGS_MODULE.split('.')[0]
       
   199     })
       
   200     return HttpResponse(t.render(c), mimetype='text/html')
       
   201 
       
   202 def _get_lines_from_file(filename, lineno, context_lines, loader=None, module_name=None):
       
   203     """
       
   204     Returns context_lines before and after lineno from file.
       
   205     Returns (pre_context_lineno, pre_context, context_line, post_context).
       
   206     """
       
   207     source = None
       
   208     if loader is not None and hasattr(loader, "get_source"):
       
   209         source = loader.get_source(module_name)
       
   210         if source is not None:
       
   211             source = source.splitlines()
       
   212     if source is None:
       
   213         try:
       
   214             f = open(filename)
       
   215             try:
       
   216                 source = f.readlines()
       
   217             finally:
       
   218                 f.close()
       
   219         except (OSError, IOError):
       
   220             pass
       
   221     if source is None:
       
   222         return None, [], None, []
       
   223 
       
   224     encoding = 'ascii'
       
   225     for line in source[:2]:
       
   226         # File coding may be specified. Match pattern from PEP-263
       
   227         # (http://www.python.org/dev/peps/pep-0263/)
       
   228         match = re.search(r'coding[:=]\s*([-\w.]+)', line)
       
   229         if match:
       
   230             encoding = match.group(1)
       
   231             break
       
   232     source = [unicode(sline, encoding, 'replace') for sline in source]
       
   233 
       
   234     lower_bound = max(0, lineno - context_lines)
       
   235     upper_bound = lineno + context_lines
       
   236 
       
   237     pre_context = [line.strip('\n') for line in source[lower_bound:lineno]]
       
   238     context_line = source[lineno].strip('\n')
       
   239     post_context = [line.strip('\n') for line in source[lineno+1:upper_bound]]
       
   240 
       
   241     return lower_bound, pre_context, context_line, post_context
       
   242 
       
   243 #
       
   244 # Templates are embedded in the file so that we know the error handler will
       
   245 # always work even if the template loader is broken.
       
   246 #
       
   247 
       
   248 TECHNICAL_500_TEMPLATE = """
       
   249 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
       
   250 <html lang="en">
       
   251 <head>
       
   252   <meta http-equiv="content-type" content="text/html; charset=utf-8">
       
   253   <meta name="robots" content="NONE,NOARCHIVE">
       
   254   <title>{{ exception_type }} at {{ request.path|escape }}</title>
       
   255   <style type="text/css">
       
   256     html * { padding:0; margin:0; }
       
   257     body * { padding:10px 20px; }
       
   258     body * * { padding:0; }
       
   259     body { font:small sans-serif; }
       
   260     body>div { border-bottom:1px solid #ddd; }
       
   261     h1 { font-weight:normal; }
       
   262     h2 { margin-bottom:.8em; }
       
   263     h2 span { font-size:80%; color:#666; font-weight:normal; }
       
   264     h3 { margin:1em 0 .5em 0; }
       
   265     h4 { margin:0 0 .5em 0; font-weight: normal; }
       
   266     table { border:1px solid #ccc; border-collapse: collapse; width:100%; background:white; }
       
   267     tbody td, tbody th { vertical-align:top; padding:2px 3px; }
       
   268     thead th { padding:1px 6px 1px 3px; background:#fefefe; text-align:left; font-weight:normal; font-size:11px; border:1px solid #ddd; }
       
   269     tbody th { width:12em; text-align:right; color:#666; padding-right:.5em; }
       
   270     table.vars { margin:5px 0 2px 40px; }
       
   271     table.vars td, table.req td { font-family:monospace; }
       
   272     table td.code { width:100%; }
       
   273     table td.code div { overflow:hidden; }
       
   274     table.source th { color:#666; }
       
   275     table.source td { font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
       
   276     ul.traceback { list-style-type:none; }
       
   277     ul.traceback li.frame { margin-bottom:1em; }
       
   278     div.context { margin: 10px 0; }
       
   279     div.context ol { padding-left:30px; margin:0 10px; list-style-position: inside; }
       
   280     div.context ol li { font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
       
   281     div.context ol.context-line li { color:black; background-color:#ccc; }
       
   282     div.context ol.context-line li span { float: right; }
       
   283     div.commands { margin-left: 40px; }
       
   284     div.commands a { color:black; text-decoration:none; }
       
   285     #summary { background: #ffc; }
       
   286     #summary h2 { font-weight: normal; color: #666; }
       
   287     #explanation { background:#eee; }
       
   288     #template, #template-not-exist { background:#f6f6f6; }
       
   289     #template-not-exist ul { margin: 0 0 0 20px; }
       
   290     #unicode-hint { background:#eee; }
       
   291     #traceback { background:#eee; }
       
   292     #requestinfo { background:#f6f6f6; padding-left:120px; }
       
   293     #summary table { border:none; background:transparent; }
       
   294     #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
       
   295     #requestinfo h3 { margin-bottom:-1em; }
       
   296     .error { background: #ffc; }
       
   297     .specific { color:#cc3300; font-weight:bold; }
       
   298     h2 span.commands { font-size:.7em;}
       
   299     span.commands a:link {color:#5E5694;}
       
   300   </style>
       
   301   <script type="text/javascript">
       
   302   //<!--
       
   303     function getElementsByClassName(oElm, strTagName, strClassName){
       
   304         // Written by Jonathan Snook, http://www.snook.ca/jon; Add-ons by Robert Nyman, http://www.robertnyman.com
       
   305         var arrElements = (strTagName == "*" && document.all)? document.all :
       
   306         oElm.getElementsByTagName(strTagName);
       
   307         var arrReturnElements = new Array();
       
   308         strClassName = strClassName.replace(/\-/g, "\\-");
       
   309         var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
       
   310         var oElement;
       
   311         for(var i=0; i<arrElements.length; i++){
       
   312             oElement = arrElements[i];
       
   313             if(oRegExp.test(oElement.className)){
       
   314                 arrReturnElements.push(oElement);
       
   315             }
       
   316         }
       
   317         return (arrReturnElements)
       
   318     }
       
   319     function hideAll(elems) {
       
   320       for (var e = 0; e < elems.length; e++) {
       
   321         elems[e].style.display = 'none';
       
   322       }
       
   323     }
       
   324     window.onload = function() {
       
   325       hideAll(getElementsByClassName(document, 'table', 'vars'));
       
   326       hideAll(getElementsByClassName(document, 'ol', 'pre-context'));
       
   327       hideAll(getElementsByClassName(document, 'ol', 'post-context'));
       
   328       hideAll(getElementsByClassName(document, 'div', 'pastebin'));
       
   329     }
       
   330     function toggle() {
       
   331       for (var i = 0; i < arguments.length; i++) {
       
   332         var e = document.getElementById(arguments[i]);
       
   333         if (e) {
       
   334           e.style.display = e.style.display == 'none' ? 'block' : 'none';
       
   335         }
       
   336       }
       
   337       return false;
       
   338     }
       
   339     function varToggle(link, id) {
       
   340       toggle('v' + id);
       
   341       var s = link.getElementsByTagName('span')[0];
       
   342       var uarr = String.fromCharCode(0x25b6);
       
   343       var darr = String.fromCharCode(0x25bc);
       
   344       s.innerHTML = s.innerHTML == uarr ? darr : uarr;
       
   345       return false;
       
   346     }
       
   347     function switchPastebinFriendly(link) {
       
   348       s1 = "Switch to copy-and-paste view";
       
   349       s2 = "Switch back to interactive view";
       
   350       link.innerHTML = link.innerHTML == s1 ? s2 : s1;
       
   351       toggle('browserTraceback', 'pastebinTraceback');
       
   352       return false;
       
   353     }
       
   354     //-->
       
   355   </script>
       
   356 </head>
       
   357 <body>
       
   358 <div id="summary">
       
   359   <h1>{{ exception_type }} at {{ request.path|escape }}</h1>
       
   360   <h2>{{ exception_value|escape }}</h2>
       
   361   <table class="meta">
       
   362     <tr>
       
   363       <th>Request Method:</th>
       
   364       <td>{{ request.META.REQUEST_METHOD }}</td>
       
   365     </tr>
       
   366     <tr>
       
   367       <th>Request URL:</th>
       
   368       <td>{{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path|escape }}</td>
       
   369     </tr>
       
   370     <tr>
       
   371       <th>Exception Type:</th>
       
   372       <td>{{ exception_type }}</td>
       
   373     </tr>
       
   374     <tr>
       
   375       <th>Exception Value:</th>
       
   376       <td>{{ exception_value|escape }}</td>
       
   377     </tr>
       
   378     <tr>
       
   379       <th>Exception Location:</th>
       
   380       <td>{{ lastframe.filename|escape }} in {{ lastframe.function|escape }}, line {{ lastframe.lineno }}</td>
       
   381     </tr>
       
   382     <tr>
       
   383       <th>Python Executable:</th>
       
   384       <td>{{ sys_executable|escape }}</td>
       
   385     </tr>
       
   386     <tr>
       
   387       <th>Python Version:</th>
       
   388       <td>{{ sys_version_info }}</td>
       
   389     </tr>
       
   390     <tr>
       
   391       <th>Python Path:</th>
       
   392       <td>{{ sys_path }}</td>
       
   393     </tr>
       
   394     <tr>
       
   395       <th>Server time:</th>
       
   396       <td>{{server_time|date:"r"}}</td>
       
   397     </tr>
       
   398   </table>
       
   399 </div>
       
   400 {% if unicode_hint %}
       
   401 <div id="unicode-hint">
       
   402     <h2>Unicode error hint</h2>
       
   403     <p>The string that could not be encoded/decoded was: <strong>{{ unicode_hint|escape }}</strong></p>
       
   404 </div>
       
   405 {% endif %}
       
   406 {% if template_does_not_exist %}
       
   407 <div id="template-not-exist">
       
   408     <h2>Template-loader postmortem</h2>
       
   409     {% if loader_debug_info %}
       
   410         <p>Django tried loading these templates, in this order:</p>
       
   411         <ul>
       
   412         {% for loader in loader_debug_info %}
       
   413             <li>Using loader <code>{{ loader.loader }}</code>:
       
   414                 <ul>{% for t in loader.templates %}<li><code>{{ t.name }}</code> (File {% if t.exists %}exists{% else %}does not exist{% endif %})</li>{% endfor %}</ul>
       
   415             </li>
       
   416         {% endfor %}
       
   417         </ul>
       
   418     {% else %}
       
   419         <p>Django couldn't find any templates because your <code>TEMPLATE_LOADERS</code> setting is empty!</p>
       
   420     {% endif %}
       
   421 </div>
       
   422 {% endif %}
       
   423 {% if template_info %}
       
   424 <div id="template">
       
   425    <h2>Template error</h2>
       
   426    <p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p>
       
   427    <h3>{{ template_info.message }}</h3>
       
   428    <table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}">
       
   429    {% for source_line in template_info.source_lines %}
       
   430    {% ifequal source_line.0 template_info.line %}
       
   431        <tr class="error"><th>{{ source_line.0 }}</th>
       
   432        <td>{{ template_info.before }}<span class="specific">{{ template_info.during }}</span>{{ template_info.after }}</td></tr>
       
   433    {% else %}
       
   434       <tr><th>{{ source_line.0 }}</th>
       
   435       <td>{{ source_line.1 }}</td></tr>
       
   436    {% endifequal %}
       
   437    {% endfor %}
       
   438    </table>
       
   439 </div>
       
   440 {% endif %}
       
   441 <div id="traceback">
       
   442   <h2>Traceback <span class="commands"><a href="#" onclick="return switchPastebinFriendly(this);">Switch to copy-and-paste view</a></span></h2>
       
   443   {% autoescape off %}
       
   444   <div id="browserTraceback">
       
   445     <ul class="traceback">
       
   446       {% for frame in frames %}
       
   447         <li class="frame">
       
   448           <code>{{ frame.filename|escape }}</code> in <code>{{ frame.function|escape }}</code>
       
   449 
       
   450           {% if frame.context_line %}
       
   451             <div class="context" id="c{{ frame.id }}">
       
   452               {% if frame.pre_context %}
       
   453                 <ol start="{{ frame.pre_context_lineno }}" class="pre-context" id="pre{{ frame.id }}">{% for line in frame.pre_context %}{% if line %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endif %}{% endfor %}</ol>
       
   454               {% endif %}
       
   455               <ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line|escape }} <span>...</span></li></ol>
       
   456               {% if frame.post_context %}
       
   457                 <ol start='{{ frame.lineno|add:"1" }}' class="post-context" id="post{{ frame.id }}">{% for line in frame.post_context %}{% if line %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endif %}{% endfor %}</ol>
       
   458               {% endif %}
       
   459             </div>
       
   460           {% endif %}
       
   461 
       
   462           {% if frame.vars %}
       
   463             <div class="commands">
       
   464                 <a href="#" onclick="return varToggle(this, '{{ frame.id }}')"><span>&#x25b6;</span> Local vars</a>
       
   465             </div>
       
   466             <table class="vars" id="v{{ frame.id }}">
       
   467               <thead>
       
   468                 <tr>
       
   469                   <th>Variable</th>
       
   470                   <th>Value</th>
       
   471                 </tr>
       
   472               </thead>
       
   473               <tbody>
       
   474                 {% for var in frame.vars|dictsort:"0" %}
       
   475                   <tr>
       
   476                     <td>{{ var.0|escape }}</td>
       
   477                     <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
       
   478                   </tr>
       
   479                 {% endfor %}
       
   480               </tbody>
       
   481             </table>
       
   482           {% endif %}
       
   483         </li>
       
   484       {% endfor %}
       
   485     </ul>
       
   486   </div>
       
   487   {% endautoescape %}
       
   488   <form action="http://dpaste.com/" name="pasteform" id="pasteform" method="post">
       
   489   <div id="pastebinTraceback" class="pastebin">
       
   490     <input type="hidden" name="language" value="PythonConsole">
       
   491     <input type="hidden" name="title" value="{{ exception_type|escape }} at {{ request.path|escape }}">
       
   492     <input type="hidden" name="source" value="Django Dpaste Agent">
       
   493     <input type="hidden" name="poster" value="Django">
       
   494     <textarea name="content" id="traceback_area" cols="140" rows="25">
       
   495 Environment:
       
   496 
       
   497 Request Method: {{ request.META.REQUEST_METHOD }}
       
   498 Request URL: {{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path|escape }}
       
   499 Django Version: {{ django_version_info }}
       
   500 Python Version: {{ sys_version_info }}
       
   501 Installed Applications:
       
   502 {{ settings.INSTALLED_APPS|pprint }}
       
   503 Installed Middleware:
       
   504 {{ settings.MIDDLEWARE_CLASSES|pprint }}
       
   505 
       
   506 {% if template_does_not_exist %}Template Loader Error:
       
   507 {% if loader_debug_info %}Django tried loading these templates, in this order:
       
   508 {% for loader in loader_debug_info %}Using loader {{ loader.loader }}:
       
   509 {% for t in loader.templates %}{{ t.name }} (File {% if t.exists %}exists{% else %}does not exist{% endif %})
       
   510 {% endfor %}{% endfor %}
       
   511 {% else %}Django couldn't find any templates because your TEMPLATE_LOADERS setting is empty!
       
   512 {% endif %}
       
   513 {% endif %}{% if template_info %}
       
   514 Template error:
       
   515 In template {{ template_info.name }}, error at line {{ template_info.line }}
       
   516    {{ template_info.message }}{% for source_line in template_info.source_lines %}{% ifequal source_line.0 template_info.line %}
       
   517    {{ source_line.0 }} : {{ template_info.before }} {{ template_info.during }} {{ template_info.after }}
       
   518 {% else %}
       
   519    {{ source_line.0 }} : {{ source_line.1 }}
       
   520 {% endifequal %}{% endfor %}{% endif %}
       
   521 Traceback:
       
   522 {% for frame in frames %}File "{{ frame.filename|escape }}" in {{ frame.function|escape }}
       
   523 {% if frame.context_line %}  {{ frame.lineno }}. {{ frame.context_line|escape }}{% endif %}
       
   524 {% endfor %}
       
   525 Exception Type: {{ exception_type|escape }} at {{ request.path|escape }}
       
   526 Exception Value: {{ exception_value|escape }}
       
   527 </textarea>
       
   528   <br><br>
       
   529   <input type="submit" value="Share this traceback on a public Web site">
       
   530   </div>
       
   531 </form>
       
   532 </div>
       
   533 
       
   534 <div id="requestinfo">
       
   535   <h2>Request information</h2>
       
   536 
       
   537   <h3 id="get-info">GET</h3>
       
   538   {% if request.GET %}
       
   539     <table class="req">
       
   540       <thead>
       
   541         <tr>
       
   542           <th>Variable</th>
       
   543           <th>Value</th>
       
   544         </tr>
       
   545       </thead>
       
   546       <tbody>
       
   547         {% for var in request.GET.items %}
       
   548           <tr>
       
   549             <td>{{ var.0 }}</td>
       
   550             <td class="code"><div>{{ var.1|pprint }}</div></td>
       
   551           </tr>
       
   552         {% endfor %}
       
   553       </tbody>
       
   554     </table>
       
   555   {% else %}
       
   556     <p>No GET data</p>
       
   557   {% endif %}
       
   558 
       
   559   <h3 id="post-info">POST</h3>
       
   560   {% if request.POST %}
       
   561     <table class="req">
       
   562       <thead>
       
   563         <tr>
       
   564           <th>Variable</th>
       
   565           <th>Value</th>
       
   566         </tr>
       
   567       </thead>
       
   568       <tbody>
       
   569         {% for var in request.POST.items %}
       
   570           <tr>
       
   571             <td>{{ var.0 }}</td>
       
   572             <td class="code"><div>{{ var.1|pprint }}</div></td>
       
   573           </tr>
       
   574         {% endfor %}
       
   575       </tbody>
       
   576     </table>
       
   577   {% else %}
       
   578     <p>No POST data</p>
       
   579   {% endif %}
       
   580 
       
   581   <h3 id="cookie-info">COOKIES</h3>
       
   582   {% if request.COOKIES %}
       
   583     <table class="req">
       
   584       <thead>
       
   585         <tr>
       
   586           <th>Variable</th>
       
   587           <th>Value</th>
       
   588         </tr>
       
   589       </thead>
       
   590       <tbody>
       
   591         {% for var in request.COOKIES.items %}
       
   592           <tr>
       
   593             <td>{{ var.0 }}</td>
       
   594             <td class="code"><div>{{ var.1|pprint }}</div></td>
       
   595           </tr>
       
   596         {% endfor %}
       
   597       </tbody>
       
   598     </table>
       
   599   {% else %}
       
   600     <p>No cookie data</p>
       
   601   {% endif %}
       
   602 
       
   603   <h3 id="meta-info">META</h3>
       
   604   <table class="req">
       
   605     <thead>
       
   606       <tr>
       
   607         <th>Variable</th>
       
   608         <th>Value</th>
       
   609       </tr>
       
   610     </thead>
       
   611     <tbody>
       
   612       {% for var in request.META.items|dictsort:"0" %}
       
   613         <tr>
       
   614           <td>{{ var.0 }}</td>
       
   615           <td class="code"><div>{{ var.1|pprint }}</div></td>
       
   616         </tr>
       
   617       {% endfor %}
       
   618     </tbody>
       
   619   </table>
       
   620 
       
   621   <h3 id="settings-info">Settings</h3>
       
   622   <h4>Using settings module <code>{{ settings.SETTINGS_MODULE }}</code></h4>
       
   623   <table class="req">
       
   624     <thead>
       
   625       <tr>
       
   626         <th>Setting</th>
       
   627         <th>Value</th>
       
   628       </tr>
       
   629     </thead>
       
   630     <tbody>
       
   631       {% for var in settings.items|dictsort:"0" %}
       
   632         <tr>
       
   633           <td>{{ var.0 }}</td>
       
   634           <td class="code"><div>{{ var.1|pprint }}</div></td>
       
   635         </tr>
       
   636       {% endfor %}
       
   637     </tbody>
       
   638   </table>
       
   639 
       
   640 </div>
       
   641 
       
   642 <div id="explanation">
       
   643   <p>
       
   644     You're seeing this error because you have <code>DEBUG = True</code> in your
       
   645     Django settings file. Change that to <code>False</code>, and Django will
       
   646     display a standard 500 page.
       
   647   </p>
       
   648 </div>
       
   649 </body>
       
   650 </html>
       
   651 """
       
   652 
       
   653 TECHNICAL_404_TEMPLATE = """
       
   654 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
       
   655 <html lang="en">
       
   656 <head>
       
   657   <meta http-equiv="content-type" content="text/html; charset=utf-8">
       
   658   <title>Page not found at {{ request.path|escape }}</title>
       
   659   <meta name="robots" content="NONE,NOARCHIVE">
       
   660   <style type="text/css">
       
   661     html * { padding:0; margin:0; }
       
   662     body * { padding:10px 20px; }
       
   663     body * * { padding:0; }
       
   664     body { font:small sans-serif; background:#eee; }
       
   665     body>div { border-bottom:1px solid #ddd; }
       
   666     h1 { font-weight:normal; margin-bottom:.4em; }
       
   667     h1 span { font-size:60%; color:#666; font-weight:normal; }
       
   668     table { border:none; border-collapse: collapse; width:100%; }
       
   669     td, th { vertical-align:top; padding:2px 3px; }
       
   670     th { width:12em; text-align:right; color:#666; padding-right:.5em; }
       
   671     #info { background:#f6f6f6; }
       
   672     #info ol { margin: 0.5em 4em; }
       
   673     #info ol li { font-family: monospace; }
       
   674     #summary { background: #ffc; }
       
   675     #explanation { background:#eee; border-bottom: 0px none; }
       
   676   </style>
       
   677 </head>
       
   678 <body>
       
   679   <div id="summary">
       
   680     <h1>Page not found <span>(404)</span></h1>
       
   681     <table class="meta">
       
   682       <tr>
       
   683         <th>Request Method:</th>
       
   684         <td>{{ request.META.REQUEST_METHOD }}</td>
       
   685       </tr>
       
   686       <tr>
       
   687         <th>Request URL:</th>
       
   688       <td>{{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path|escape }}</td>
       
   689       </tr>
       
   690     </table>
       
   691   </div>
       
   692   <div id="info">
       
   693     {% if urlpatterns %}
       
   694       <p>
       
   695       Using the URLconf defined in <code>{{ settings.ROOT_URLCONF }}</code>,
       
   696       Django tried these URL patterns, in this order:
       
   697       </p>
       
   698       <ol>
       
   699         {% for pattern in urlpatterns %}
       
   700           <li>{{ pattern }}</li>
       
   701         {% endfor %}
       
   702       </ol>
       
   703       <p>The current URL, <code>{{ request_path|escape }}</code>, didn't match any of these.</p>
       
   704     {% else %}
       
   705       <p>{{ reason }}</p>
       
   706     {% endif %}
       
   707   </div>
       
   708 
       
   709   <div id="explanation">
       
   710     <p>
       
   711       You're seeing this error because you have <code>DEBUG = True</code> in
       
   712       your Django settings file. Change that to <code>False</code>, and Django
       
   713       will display a standard 404 page.
       
   714     </p>
       
   715   </div>
       
   716 </body>
       
   717 </html>
       
   718 """
       
   719 
       
   720 EMPTY_URLCONF_TEMPLATE = """
       
   721 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
       
   722 <html lang="en"><head>
       
   723   <meta http-equiv="content-type" content="text/html; charset=utf-8">
       
   724   <meta name="robots" content="NONE,NOARCHIVE"><title>Welcome to Django</title>
       
   725   <style type="text/css">
       
   726     html * { padding:0; margin:0; }
       
   727     body * { padding:10px 20px; }
       
   728     body * * { padding:0; }
       
   729     body { font:small sans-serif; }
       
   730     body>div { border-bottom:1px solid #ddd; }
       
   731     h1 { font-weight:normal; }
       
   732     h2 { margin-bottom:.8em; }
       
   733     h2 span { font-size:80%; color:#666; font-weight:normal; }
       
   734     h3 { margin:1em 0 .5em 0; }
       
   735     h4 { margin:0 0 .5em 0; font-weight: normal; }
       
   736     table { border:1px solid #ccc; border-collapse: collapse; width:100%; background:white; }
       
   737     tbody td, tbody th { vertical-align:top; padding:2px 3px; }
       
   738     thead th { padding:1px 6px 1px 3px; background:#fefefe; text-align:left; font-weight:normal; font-size:11px; border:1px solid #ddd; }
       
   739     tbody th { width:12em; text-align:right; color:#666; padding-right:.5em; }
       
   740     ul { margin-left: 2em; margin-top: 1em; }
       
   741     #summary { background: #e0ebff; }
       
   742     #summary h2 { font-weight: normal; color: #666; }
       
   743     #explanation { background:#eee; }
       
   744     #instructions { background:#f6f6f6; }
       
   745     #summary table { border:none; background:transparent; }
       
   746   </style>
       
   747 </head>
       
   748 
       
   749 <body>
       
   750 <div id="summary">
       
   751   <h1>It worked!</h1>
       
   752   <h2>Congratulations on your first Django-powered page.</h2>
       
   753 </div>
       
   754 
       
   755 <div id="instructions">
       
   756   <p>Of course, you haven't actually done any work yet. Here's what to do next:</p>
       
   757   <ul>
       
   758     <li>If you plan to use a database, edit the <code>DATABASE_*</code> settings in <code>{{ project_name }}/settings.py</code>.</li>
       
   759     <li>Start your first app by running <code>python {{ project_name }}/manage.py startapp [appname]</code>.</li>
       
   760   </ul>
       
   761 </div>
       
   762 
       
   763 <div id="explanation">
       
   764   <p>
       
   765     You're seeing this message because you have <code>DEBUG = True</code> in your
       
   766     Django settings file and you haven't configured any URLs. Get to work!
       
   767   </p>
       
   768 </div>
       
   769 </body></html>
       
   770 """