~ubuntu-branches/ubuntu/quantal/python-django/quantal

« back to all changes in this revision

Viewing changes to django/views/debug.py

  • Committer: Bazaar Package Importer
  • Author(s): Scott James Remnant, Eddy Mulyono
  • Date: 2008-09-16 12:18:47 UTC
  • mfrom: (1.1.5 upstream) (4.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080916121847-mg225rg5mnsdqzr0
Tags: 1.0-1ubuntu1
* Merge from Debian (LP: #264191), remaining changes:
  - Run test suite on build.

[Eddy Mulyono]
* Update patch to workaround network test case failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import os
 
2
import re
 
3
import sys
 
4
import datetime
 
5
 
1
6
from django.conf import settings
2
7
from django.template import Template, Context, TemplateDoesNotExist
3
8
from django.utils.html import escape
4
 
from django.http import HttpResponseServerError, HttpResponseNotFound
5
 
import os, re
 
9
from django.http import HttpResponse, HttpResponseServerError, HttpResponseNotFound
 
10
from django.utils.encoding import smart_unicode, smart_str
6
11
 
7
12
HIDDEN_SETTINGS = re.compile('SECRET|PASSWORD|PROFANITIES_LIST')
8
13
 
14
19
        p = template_source.find('\n', p+1)
15
20
    yield len(template_source) + 1
16
21
 
17
 
def get_template_exception_info(exc_type, exc_value, tb):
18
 
    origin, (start, end) = exc_value.source
19
 
    template_source = origin.reload()
20
 
    context_lines = 10
21
 
    line = 0
22
 
    upto = 0
23
 
    source_lines = []
24
 
    before = during = after = ""
25
 
    for num, next in enumerate(linebreak_iter(template_source)):
26
 
        if start >= upto and end <= next:
27
 
            line = num
28
 
            before = escape(template_source[upto:start])
29
 
            during = escape(template_source[start:end])
30
 
            after = escape(template_source[end:next])
31
 
        source_lines.append( (num, escape(template_source[upto:next])) )
32
 
        upto = next
33
 
    total = len(source_lines)
34
 
 
35
 
    top = max(1, line - context_lines)
36
 
    bottom = min(total, line + 1 + context_lines)
37
 
 
38
 
    template_info = {
39
 
        'message': exc_value.args[0],
40
 
        'source_lines': source_lines[top:bottom],
41
 
        'before': before,
42
 
        'during': during,
43
 
        'after': after,
44
 
        'top': top,
45
 
        'bottom': bottom,
46
 
        'total': total,
47
 
        'line': line,
48
 
        'name': origin.name,
49
 
    }
50
 
    exc_info = hasattr(exc_value, 'exc_info') and exc_value.exc_info or (exc_type, exc_value, tb)
51
 
    return exc_info + (template_info,)
52
 
 
53
22
def get_safe_settings():
54
23
    "Returns a dictionary of the settings module, with sensitive settings blurred out."
55
24
    settings_dict = {}
66
35
    Create a technical server error response. The last three arguments are
67
36
    the values returned from sys.exc_info() and friends.
68
37
    """
69
 
    template_info = None
70
 
    template_does_not_exist = False
71
 
    loader_debug_info = None
72
 
    if issubclass(exc_type, TemplateDoesNotExist):
73
 
        from django.template.loader import template_source_loaders
74
 
        template_does_not_exist = True
75
 
        loader_debug_info = []
76
 
        for loader in template_source_loaders:
 
38
    reporter = ExceptionReporter(request, exc_type, exc_value, tb)
 
39
    html = reporter.get_traceback_html()
 
40
    return HttpResponseServerError(html, mimetype='text/html')
 
41
 
 
42
class ExceptionReporter:
 
43
    """
 
44
    A class to organize and coordinate reporting on exceptions.
 
45
    """
 
46
    def __init__(self, request, exc_type, exc_value, tb):
 
47
        self.request = request
 
48
        self.exc_type = exc_type
 
49
        self.exc_value = exc_value
 
50
        self.tb = tb
 
51
 
 
52
        self.template_info = None
 
53
        self.template_does_not_exist = False
 
54
        self.loader_debug_info = None
 
55
 
 
56
        # Handle deprecated string exceptions
 
57
        if isinstance(self.exc_type, basestring):
 
58
            self.exc_value = Exception('Deprecated String Exception: %r' % self.exc_type)
 
59
            self.exc_type = type(self.exc_value)
 
60
 
 
61
    def get_traceback_html(self):
 
62
        "Return HTML code for traceback."
 
63
 
 
64
        if issubclass(self.exc_type, TemplateDoesNotExist):
 
65
            from django.template.loader import template_source_loaders
 
66
            self.template_does_not_exist = True
 
67
            self.loader_debug_info = []
 
68
            for loader in template_source_loaders:
 
69
                try:
 
70
                    source_list_func = getattr(__import__(loader.__module__, {}, {}, ['get_template_sources']), 'get_template_sources')
 
71
                    # NOTE: This assumes exc_value is the name of the template that
 
72
                    # the loader attempted to load.
 
73
                    template_list = [{'name': t, 'exists': os.path.exists(t)} \
 
74
                        for t in source_list_func(str(self.exc_value))]
 
75
                except (ImportError, AttributeError):
 
76
                    template_list = []
 
77
                self.loader_debug_info.append({
 
78
                    'loader': loader.__module__ + '.' + loader.__name__,
 
79
                    'templates': template_list,
 
80
                })
 
81
        if settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'source'):
 
82
            self.get_template_exception_info()
 
83
 
 
84
        frames = self.get_traceback_frames()
 
85
 
 
86
        unicode_hint = ''
 
87
        if issubclass(self.exc_type, UnicodeError):
 
88
            start = getattr(self.exc_value, 'start', None)
 
89
            end = getattr(self.exc_value, 'end', None)
 
90
            if start is not None and end is not None:
 
91
                unicode_str = self.exc_value.args[1]
 
92
                unicode_hint = smart_unicode(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace')
 
93
        from django import get_version
 
94
        t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template')
 
95
        c = Context({
 
96
            'exception_type': self.exc_type.__name__,
 
97
            'exception_value': smart_unicode(self.exc_value, errors='replace'),
 
98
            'unicode_hint': unicode_hint,
 
99
            'frames': frames,
 
100
            'lastframe': frames[-1],
 
101
            'request': self.request,
 
102
            'request_protocol': self.request.is_secure() and "https" or "http",
 
103
            'settings': get_safe_settings(),
 
104
            'sys_executable': sys.executable,
 
105
            'sys_version_info': '%d.%d.%d' % sys.version_info[0:3],
 
106
            'server_time': datetime.datetime.now(),
 
107
            'django_version_info': get_version(),
 
108
            'sys_path' : sys.path,
 
109
            'template_info': self.template_info,
 
110
            'template_does_not_exist': self.template_does_not_exist,
 
111
            'loader_debug_info': self.loader_debug_info,
 
112
        })
 
113
        return t.render(c)
 
114
 
 
115
    def get_template_exception_info(self):
 
116
        origin, (start, end) = self.exc_value.source
 
117
        template_source = origin.reload()
 
118
        context_lines = 10
 
119
        line = 0
 
120
        upto = 0
 
121
        source_lines = []
 
122
        before = during = after = ""
 
123
        for num, next in enumerate(linebreak_iter(template_source)):
 
124
            if start >= upto and end <= next:
 
125
                line = num
 
126
                before = escape(template_source[upto:start])
 
127
                during = escape(template_source[start:end])
 
128
                after = escape(template_source[end:next])
 
129
            source_lines.append( (num, escape(template_source[upto:next])) )
 
130
            upto = next
 
131
        total = len(source_lines)
 
132
 
 
133
        top = max(1, line - context_lines)
 
134
        bottom = min(total, line + 1 + context_lines)
 
135
 
 
136
        self.template_info = {
 
137
            'message': self.exc_value.args[0],
 
138
            'source_lines': source_lines[top:bottom],
 
139
            'before': before,
 
140
            'during': during,
 
141
            'after': after,
 
142
            'top': top,
 
143
            'bottom': bottom,
 
144
            'total': total,
 
145
            'line': line,
 
146
            'name': origin.name,
 
147
        }
 
148
 
 
149
    def _get_lines_from_file(self, filename, lineno, context_lines, loader=None, module_name=None):
 
150
        """
 
151
        Returns context_lines before and after lineno from file.
 
152
        Returns (pre_context_lineno, pre_context, context_line, post_context).
 
153
        """
 
154
        source = None
 
155
        if loader is not None and hasattr(loader, "get_source"):
 
156
            source = loader.get_source(module_name)
 
157
            if source is not None:
 
158
                source = source.splitlines()
 
159
        if source is None:
77
160
            try:
78
 
                source_list_func = getattr(__import__(loader.__module__, {}, {}, ['get_template_sources']), 'get_template_sources')
79
 
                # NOTE: This assumes exc_value is the name of the template that
80
 
                # the loader attempted to load.
81
 
                template_list = [{'name': t, 'exists': os.path.exists(t)} \
82
 
                    for t in source_list_func(str(exc_value))]
83
 
            except (ImportError, AttributeError):
84
 
                template_list = []
85
 
            loader_debug_info.append({
86
 
                'loader': loader.__module__ + '.' + loader.__name__,
87
 
                'templates': template_list,
88
 
            })
89
 
    if settings.TEMPLATE_DEBUG and hasattr(exc_value, 'source'):
90
 
        exc_type, exc_value, tb, template_info = get_template_exception_info(exc_type, exc_value, tb)
91
 
    frames = []
92
 
    while tb is not None:
93
 
        filename = tb.tb_frame.f_code.co_filename
94
 
        function = tb.tb_frame.f_code.co_name
95
 
        lineno = tb.tb_lineno - 1
96
 
        pre_context_lineno, pre_context, context_line, post_context = _get_lines_from_file(filename, lineno, 7)
97
 
        if pre_context_lineno:
98
 
            frames.append({
99
 
                'tb': tb,
100
 
                'filename': filename,
101
 
                'function': function,
102
 
                'lineno': lineno + 1,
103
 
                'vars': tb.tb_frame.f_locals.items(),
104
 
                'id': id(tb),
105
 
                'pre_context': pre_context,
106
 
                'context_line': context_line,
107
 
                'post_context': post_context,
108
 
                'pre_context_lineno': pre_context_lineno + 1,
109
 
            })
110
 
        tb = tb.tb_next
111
 
 
112
 
    if not frames:
113
 
        frames = [{
114
 
            'filename': '&lt;unknown&gt;',
115
 
            'function': '?',
116
 
            'lineno': '?',
117
 
        }]
118
 
    t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template')
119
 
    c = Context({
120
 
        'exception_type': exc_type.__name__,
121
 
        'exception_value': exc_value,
122
 
        'frames': frames,
123
 
        'lastframe': frames[-1],
124
 
        'request': request,
125
 
        'request_protocol': request.is_secure() and "https" or "http",
126
 
        'settings': get_safe_settings(),
127
 
        'template_info': template_info,
128
 
        'template_does_not_exist': template_does_not_exist,
129
 
        'loader_debug_info': loader_debug_info,
130
 
    })
131
 
    return HttpResponseServerError(t.render(c), mimetype='text/html')
 
161
                f = open(filename)
 
162
                try:
 
163
                    source = f.readlines()
 
164
                finally:
 
165
                    f.close()
 
166
            except (OSError, IOError):
 
167
                pass
 
168
        if source is None:
 
169
            return None, [], None, []
 
170
 
 
171
        encoding = 'ascii'
 
172
        for line in source[:2]:
 
173
            # File coding may be specified. Match pattern from PEP-263
 
174
            # (http://www.python.org/dev/peps/pep-0263/)
 
175
            match = re.search(r'coding[:=]\s*([-\w.]+)', line)
 
176
            if match:
 
177
                encoding = match.group(1)
 
178
                break
 
179
        source = [unicode(sline, encoding, 'replace') for sline in source]
 
180
 
 
181
        lower_bound = max(0, lineno - context_lines)
 
182
        upper_bound = lineno + context_lines
 
183
 
 
184
        pre_context = [line.strip('\n') for line in source[lower_bound:lineno]]
 
185
        context_line = source[lineno].strip('\n')
 
186
        post_context = [line.strip('\n') for line in source[lineno+1:upper_bound]]
 
187
 
 
188
        return lower_bound, pre_context, context_line, post_context
 
189
 
 
190
    def get_traceback_frames(self):
 
191
        frames = []
 
192
        tb = self.tb
 
193
        while tb is not None:
 
194
            # support for __traceback_hide__ which is used by a few libraries
 
195
            # to hide internal frames.
 
196
            if tb.tb_frame.f_locals.get('__traceback_hide__'):
 
197
                tb = tb.tb_next
 
198
                continue
 
199
            filename = tb.tb_frame.f_code.co_filename
 
200
            function = tb.tb_frame.f_code.co_name
 
201
            lineno = tb.tb_lineno - 1
 
202
            loader = tb.tb_frame.f_globals.get('__loader__')
 
203
            module_name = tb.tb_frame.f_globals.get('__name__')
 
204
            pre_context_lineno, pre_context, context_line, post_context = self._get_lines_from_file(filename, lineno, 7, loader, module_name)
 
205
            if pre_context_lineno is not None:
 
206
                frames.append({
 
207
                    'tb': tb,
 
208
                    'filename': filename,
 
209
                    'function': function,
 
210
                    'lineno': lineno + 1,
 
211
                    'vars': tb.tb_frame.f_locals.items(),
 
212
                    'id': id(tb),
 
213
                    'pre_context': pre_context,
 
214
                    'context_line': context_line,
 
215
                    'post_context': post_context,
 
216
                    'pre_context_lineno': pre_context_lineno + 1,
 
217
                })
 
218
            tb = tb.tb_next
 
219
 
 
220
        if not frames:
 
221
            frames = [{
 
222
                'filename': '&lt;unknown&gt;',
 
223
                'function': '?',
 
224
                'lineno': '?',
 
225
                'context_line': '???',
 
226
            }]
 
227
 
 
228
        return frames
 
229
 
 
230
    def format_exception(self):
 
231
        """
 
232
        Return the same data as from traceback.format_exception.
 
233
        """
 
234
        import traceback
 
235
        frames = self.get_traceback_frames()
 
236
        tb = [ (f['filename'], f['lineno'], f['function'], f['context_line']) for f in frames ]
 
237
        list = ['Traceback (most recent call last):\n']
 
238
        list += traceback.format_list(tb)
 
239
        list += traceback.format_exception_only(self.exc_type, self.exc_value)
 
240
        return list
 
241
 
132
242
 
133
243
def technical_404_response(request, exception):
134
244
    "Create a technical 404 error response. The exception should be the Http404."
144
254
    t = Template(TECHNICAL_404_TEMPLATE, name='Technical 404 template')
145
255
    c = Context({
146
256
        'root_urlconf': settings.ROOT_URLCONF,
 
257
        'request_path': request.path_info[1:], # Trim leading slash
147
258
        'urlpatterns': tried,
148
 
        'reason': str(exception),
 
259
        'reason': smart_str(exception, errors='replace'),
149
260
        'request': request,
150
261
        'request_protocol': request.is_secure() and "https" or "http",
151
262
        'settings': get_safe_settings(),
158
269
    c = Context({
159
270
        'project_name': settings.SETTINGS_MODULE.split('.')[0]
160
271
    })
161
 
    return HttpResponseNotFound(t.render(c), mimetype='text/html')
162
 
 
163
 
def _get_lines_from_file(filename, lineno, context_lines):
164
 
    """
165
 
    Returns context_lines before and after lineno from file.
166
 
    Returns (pre_context_lineno, pre_context, context_line, post_context).
167
 
    """
168
 
    try:
169
 
        source = open(filename).readlines()
170
 
        lower_bound = max(0, lineno - context_lines)
171
 
        upper_bound = lineno + context_lines
172
 
 
173
 
        pre_context = [line.strip('\n') for line in source[lower_bound:lineno]]
174
 
        context_line = source[lineno].strip('\n')
175
 
        post_context = [line.strip('\n') for line in source[lineno+1:upper_bound]]
176
 
 
177
 
        return lower_bound, pre_context, context_line, post_context
178
 
    except (OSError, IOError):
179
 
        return None, [], None, []
 
272
    return HttpResponse(t.render(c), mimetype='text/html')
180
273
 
181
274
#
182
275
# Templates are embedded in the file so that we know the error handler will
187
280
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
188
281
<html lang="en">
189
282
<head>
190
 
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
191
 
  <meta name="robots" content="NONE,NOARCHIVE" />
192
 
  <title>{{ exception_type }} at {{ request.path|escape }}</title>
 
283
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
 
284
  <meta name="robots" content="NONE,NOARCHIVE">
 
285
  <title>{{ exception_type }} at {{ request.path_info|escape }}</title>
193
286
  <style type="text/css">
194
287
    html * { padding:0; margin:0; }
195
288
    body * { padding:10px 20px; }
225
318
    #explanation { background:#eee; }
226
319
    #template, #template-not-exist { background:#f6f6f6; }
227
320
    #template-not-exist ul { margin: 0 0 0 20px; }
 
321
    #unicode-hint { background:#eee; }
228
322
    #traceback { background:#eee; }
229
323
    #requestinfo { background:#f6f6f6; padding-left:120px; }
230
324
    #summary table { border:none; background:transparent; }
232
326
    #requestinfo h3 { margin-bottom:-1em; }
233
327
    .error { background: #ffc; }
234
328
    .specific { color:#cc3300; font-weight:bold; }
 
329
    h2 span.commands { font-size:.7em;}
 
330
    span.commands a:link {color:#5E5694;}
 
331
    pre.exception_value { font-family: sans-serif; color: #666; font-size: 1.5em; margin: 10px 0 10px 0; }
235
332
  </style>
236
333
  <script type="text/javascript">
237
334
  //<!--
290
387
  </script>
291
388
</head>
292
389
<body>
293
 
 
294
390
<div id="summary">
295
 
  <h1>{{ exception_type }} at {{ request.path|escape }}</h1>
296
 
  <h2>{{ exception_value|escape }}</h2>
 
391
  <h1>{{ exception_type }} at {{ request.path_info|escape }}</h1>
 
392
  <pre class="exception_value">{{ exception_value|escape }}</pre>
297
393
  <table class="meta">
298
394
    <tr>
299
395
      <th>Request Method:</th>
301
397
    </tr>
302
398
    <tr>
303
399
      <th>Request URL:</th>
304
 
      <td>{{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path|escape }}</td>
 
400
      <td>{{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path_info|escape }}</td>
305
401
    </tr>
306
402
    <tr>
307
403
      <th>Exception Type:</th>
309
405
    </tr>
310
406
    <tr>
311
407
      <th>Exception Value:</th>
312
 
      <td>{{ exception_value|escape }}</td>
 
408
      <td><pre>{{ exception_value|escape }}<pre></td>
313
409
    </tr>
314
410
    <tr>
315
411
      <th>Exception Location:</th>
316
 
      <td>{{ lastframe.filename }} in {{ lastframe.function }}, line {{ lastframe.lineno }}</td>
 
412
      <td>{{ lastframe.filename|escape }} in {{ lastframe.function|escape }}, line {{ lastframe.lineno }}</td>
 
413
    </tr>
 
414
    <tr>
 
415
      <th>Python Executable:</th>
 
416
      <td>{{ sys_executable|escape }}</td>
 
417
    </tr>
 
418
    <tr>
 
419
      <th>Python Version:</th>
 
420
      <td>{{ sys_version_info }}</td>
 
421
    </tr>
 
422
    <tr>
 
423
      <th>Python Path:</th>
 
424
      <td>{{ sys_path }}</td>
 
425
    </tr>
 
426
    <tr>
 
427
      <th>Server time:</th>
 
428
      <td>{{server_time|date:"r"}}</td>
317
429
    </tr>
318
430
  </table>
319
431
</div>
 
432
{% if unicode_hint %}
 
433
<div id="unicode-hint">
 
434
    <h2>Unicode error hint</h2>
 
435
    <p>The string that could not be encoded/decoded was: <strong>{{ unicode_hint|escape }}</strong></p>
 
436
</div>
 
437
{% endif %}
320
438
{% if template_does_not_exist %}
321
439
<div id="template-not-exist">
322
440
    <h2>Template-loader postmortem</h2>
338
456
<div id="template">
339
457
   <h2>Template error</h2>
340
458
   <p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p>
341
 
   <h3>{{ template_info.message|escape }}</h3>
 
459
   <h3>{{ template_info.message }}</h3>
342
460
   <table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}">
343
461
   {% for source_line in template_info.source_lines %}
344
462
   {% ifequal source_line.0 template_info.line %}
353
471
</div>
354
472
{% endif %}
355
473
<div id="traceback">
356
 
  <h2>Traceback <span>(innermost last)</span></h2>
357
 
  <div class="commands"><a href="#" onclick="return switchPastebinFriendly(this);">Switch to copy-and-paste view</a></div>
358
 
  <br/>
 
474
  <h2>Traceback <span class="commands"><a href="#" onclick="return switchPastebinFriendly(this);">Switch to copy-and-paste view</a></span></h2>
 
475
  {% autoescape off %}
359
476
  <div id="browserTraceback">
360
477
    <ul class="traceback">
361
478
      {% for frame in frames %}
362
479
        <li class="frame">
363
 
          <code>{{ frame.filename }}</code> in <code>{{ frame.function }}</code>
 
480
          <code>{{ frame.filename|escape }}</code> in <code>{{ frame.function|escape }}</code>
364
481
 
365
482
          {% if frame.context_line %}
366
483
            <div class="context" id="c{{ frame.id }}">
388
505
              <tbody>
389
506
                {% for var in frame.vars|dictsort:"0" %}
390
507
                  <tr>
391
 
                    <td>{{ var.0 }}</td>
 
508
                    <td>{{ var.0|escape }}</td>
392
509
                    <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
393
510
                  </tr>
394
511
                {% endfor %}
399
516
      {% endfor %}
400
517
    </ul>
401
518
  </div>
 
519
  {% endautoescape %}
 
520
  <form action="http://dpaste.com/" name="pasteform" id="pasteform" method="post">
402
521
  <div id="pastebinTraceback" class="pastebin">
403
 
    <table>
404
 
      <tbody>
405
 
        <tr>
406
 
          <td>
407
 
            <code>
408
 
Traceback (most recent call last):<br/>
409
 
{% for frame in frames %}
410
 
  File "{{ frame.filename }}" in {{ frame.function }}<br/>
411
 
  {% if frame.context_line %}
412
 
    &nbsp;&nbsp;{{ frame.lineno }}. {{ frame.context_line|escape }}<br/>
413
 
  {% endif %}
414
 
{% endfor %}<br/>
415
 
&nbsp;&nbsp;{{ exception_type }} at {{ request.path|escape }}<br/>
416
 
&nbsp;&nbsp;{{ exception_value|escape }}</code>
417
 
          </td>
418
 
        </tr>
419
 
      </tbody>
420
 
    </table>
 
522
    <input type="hidden" name="language" value="PythonConsole">
 
523
    <input type="hidden" name="title" value="{{ exception_type|escape }} at {{ request.path_info|escape }}">
 
524
    <input type="hidden" name="source" value="Django Dpaste Agent">
 
525
    <input type="hidden" name="poster" value="Django">
 
526
    <textarea name="content" id="traceback_area" cols="140" rows="25">
 
527
Environment:
 
528
 
 
529
Request Method: {{ request.META.REQUEST_METHOD }}
 
530
Request URL: {{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path_info|escape }}
 
531
Django Version: {{ django_version_info }}
 
532
Python Version: {{ sys_version_info }}
 
533
Installed Applications:
 
534
{{ settings.INSTALLED_APPS|pprint }}
 
535
Installed Middleware:
 
536
{{ settings.MIDDLEWARE_CLASSES|pprint }}
 
537
 
 
538
{% if template_does_not_exist %}Template Loader Error:
 
539
{% if loader_debug_info %}Django tried loading these templates, in this order:
 
540
{% for loader in loader_debug_info %}Using loader {{ loader.loader }}:
 
541
{% for t in loader.templates %}{{ t.name }} (File {% if t.exists %}exists{% else %}does not exist{% endif %})
 
542
{% endfor %}{% endfor %}
 
543
{% else %}Django couldn't find any templates because your TEMPLATE_LOADERS setting is empty!
 
544
{% endif %}
 
545
{% endif %}{% if template_info %}
 
546
Template error:
 
547
In template {{ template_info.name }}, error at line {{ template_info.line }}
 
548
   {{ template_info.message }}{% for source_line in template_info.source_lines %}{% ifequal source_line.0 template_info.line %}
 
549
   {{ source_line.0 }} : {{ template_info.before }} {{ template_info.during }} {{ template_info.after }}
 
550
{% else %}
 
551
   {{ source_line.0 }} : {{ source_line.1 }}
 
552
{% endifequal %}{% endfor %}{% endif %}
 
553
Traceback:
 
554
{% for frame in frames %}File "{{ frame.filename|escape }}" in {{ frame.function|escape }}
 
555
{% if frame.context_line %}  {{ frame.lineno }}. {{ frame.context_line|escape }}{% endif %}
 
556
{% endfor %}
 
557
Exception Type: {{ exception_type|escape }} at {{ request.path_info|escape }}
 
558
Exception Value: {{ exception_value|escape }}
 
559
</textarea>
 
560
  <br><br>
 
561
  <input type="submit" value="Share this traceback on a public Web site">
421
562
  </div>
 
563
</form>
422
564
</div>
423
565
 
424
566
<div id="requestinfo">
437
579
        {% for var in request.GET.items %}
438
580
          <tr>
439
581
            <td>{{ var.0 }}</td>
440
 
            <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
 
582
            <td class="code"><div>{{ var.1|pprint }}</div></td>
441
583
          </tr>
442
584
        {% endfor %}
443
585
      </tbody>
459
601
        {% for var in request.POST.items %}
460
602
          <tr>
461
603
            <td>{{ var.0 }}</td>
462
 
            <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
 
604
            <td class="code"><div>{{ var.1|pprint }}</div></td>
463
605
          </tr>
464
606
        {% endfor %}
465
607
      </tbody>
481
623
        {% for var in request.COOKIES.items %}
482
624
          <tr>
483
625
            <td>{{ var.0 }}</td>
484
 
            <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
 
626
            <td class="code"><div>{{ var.1|pprint }}</div></td>
485
627
          </tr>
486
628
        {% endfor %}
487
629
      </tbody>
502
644
      {% for var in request.META.items|dictsort:"0" %}
503
645
        <tr>
504
646
          <td>{{ var.0 }}</td>
505
 
          <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
 
647
          <td class="code"><div>{{ var.1|pprint }}</div></td>
506
648
        </tr>
507
649
      {% endfor %}
508
650
    </tbody>
521
663
      {% for var in settings.items|dictsort:"0" %}
522
664
        <tr>
523
665
          <td>{{ var.0 }}</td>
524
 
          <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
 
666
          <td class="code"><div>{{ var.1|pprint }}</div></td>
525
667
        </tr>
526
668
      {% endfor %}
527
669
    </tbody>
536
678
    display a standard 500 page.
537
679
  </p>
538
680
</div>
539
 
 
540
681
</body>
541
682
</html>
542
683
"""
545
686
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
546
687
<html lang="en">
547
688
<head>
548
 
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
549
 
  <title>Page not found at {{ request.path|escape }}</title>
550
 
  <meta name="robots" content="NONE,NOARCHIVE" />
 
689
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
 
690
  <title>Page not found at {{ request.path_info|escape }}</title>
 
691
  <meta name="robots" content="NONE,NOARCHIVE">
551
692
  <style type="text/css">
552
693
    html * { padding:0; margin:0; }
553
694
    body * { padding:10px 20px; }
576
717
      </tr>
577
718
      <tr>
578
719
        <th>Request URL:</th>
579
 
      <td>{{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path|escape }}</td>
 
720
      <td>{{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path_info|escape }}</td>
580
721
      </tr>
581
722
    </table>
582
723
  </div>
588
729
      </p>
589
730
      <ol>
590
731
        {% for pattern in urlpatterns %}
591
 
          <li>{{ pattern|escape }}</li>
 
732
          <li>{{ pattern }}</li>
592
733
        {% endfor %}
593
734
      </ol>
594
 
      <p>The current URL, <code>{{ request.path|escape }}</code>, didn't match any of these.</p>
 
735
      <p>The current URL, <code>{{ request_path|escape }}</code>, didn't match any of these.</p>
595
736
    {% else %}
596
 
      <p>{{ reason|escape }}</p>
 
737
      <p>{{ reason }}</p>
597
738
    {% endif %}
598
739
  </div>
599
740