+++ /dev/null
-"""
-Debug Toolbar middleware
-"""
-import re
-from django.conf import settings
-from django.utils.encoding import smart_str
-from debug_toolbar.toolbar.loader import DebugToolbar
-
-_HTML_TYPES = ('text/html', 'application/xhtml+xml')
-_END_HEAD_RE = re.compile(r'</head>', re.IGNORECASE)
-_END_BODY_RE = re.compile(r'<body[^<]*>', re.IGNORECASE)
-
-class DebugToolbarMiddleware(object):
- """
- Middleware to set up Debug Toolbar on incoming request and render toolbar
- on outgoing response.
- """
- def __init__(self):
- self.debug_toolbar = None
-
- def show_toolbar(self, request):
- if not settings.DEBUG:
- return False
- if not request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
- return False
- return True
-
- def process_request(self, request):
- if self.show_toolbar(request):
- self.debug_toolbar = DebugToolbar(request)
- self.debug_toolbar.load_panels()
- debug = request.GET.get('djDebug')
- # kinda ugly, needs changes to the loader to optimize
- for panel in self.debug_toolbar.panels:
- response = panel.process_request(request)
- if not response:
- if debug == panel.name:
- response = panel.process_ajax(request)
- if response:
- response.skip_debug_response = True
- return response
-
- def process_view(self, request, callback, callback_args, callback_kwargs):
- if self.show_toolbar(request):
- for panel in self.debug_toolbar.panels:
- cb = panel.process_view(request, callback, callback_args, callback_kwargs)
- if cb:
- callback = cb
- return callback
-
- def process_response(self, request, response):
- if self.show_toolbar(request) and not getattr(response, 'skip_debug_response', False):
- if response['Content-Type'].split(';')[0] in _HTML_TYPES and not request.is_ajax():
- # Saving this here in case we ever need to inject into <head>
- #response.content = _END_HEAD_RE.sub(smart_str(self.debug_toolbar.render_styles() + "%s" % match.group()), response.content)
- for panel in self.debug_toolbar.panels:
- nr = panel.process_response(request, response)
- # Incase someone forgets `return response`
- if nr: response = nr
- response.content = _END_BODY_RE.sub(smart_str('<body>' + self.debug_toolbar.render_toolbar()), response.content)
- return response
+++ /dev/null
-"""Base DebugPanel class"""
-
-class DebugPanel(object):
- """
- Base class for debug panels.
- """
- # name = Base
-
- def __init__(self, request):
- self.request = request
-
- def process_request(self, request):
- return None
-
- def process_response(self, request, response):
- return response
-
- def process_view(self, request, callback, callback_args, callback_kwargs):
- return None
-
- def dom_id(self):
- return 'djDebug%sPanel' % (self.name.replace(' ', ''))
-
- def title(self):
- raise NotImplementedError
-
- def url(self):
- raise NotImplementedError
-
- def content(self):
- # TODO: This is a bit flaky in that panel.content() returns a string
- # that gets inserted into the toolbar HTML template.
- raise NotImplementedError
+++ /dev/null
-from debug_toolbar.panels import DebugPanel
-try: from cStringIO import StringIO
-except ImportError: import StringIO
-from django.core import cache
-from django.core.cache.backends.base import BaseCache
-import time
-import inspect
-import os.path
-from django.template.loader import render_to_string
-
-class CacheStatTracker(BaseCache):
- """A small class used to track cache calls."""
- def __init__(self, cache):
- self.cache = cache
- self.reset()
-
- def reset(self):
- self.calls = []
- self.hits = 0
- self.misses = 0
- self.sets = 0
- self.gets = 0
- self.get_many = 0
- self.deletes = 0
- self.total_time = 0
-
- def _get_func_info(self):
- stack = inspect.stack()[2]
- return (os.path.basename(stack[1]), stack[2], stack[3], stack[4])
-
- def get(self, key, default=None):
- t = time.time()
- value = self.cache.get(key, default)
- this_time = time.time()-t
- self.total_time += this_time*1000
- if value is None:
- self.misses += 1
- else:
- self.hits += 1
- self.gets += 1
- self.calls.append((this_time, 'get', (key,), self._get_func_info()))
- return value
-
- def set(self, key, value, timeout=None):
- t = time.time()
- self.cache.set(key, value, timeout)
- this_time = time.time()-t
- self.total_time += this_time*1000
- self.sets += 1
- self.calls.append((this_time, 'set', (key, value, timeout), self._get_func_info()))
-
- def delete(self, key):
- t = time.time()
- self.instance.delete(key, value)
- this_time = time.time()-t
- self.total_time += this_time*1000
- self.deletes += 1
- self.calls.append((this_time, 'delete', (key,), self._get_func_info()))
-
- def get_many(self, keys):
- t = time.time()
- results = self.cache.get_many(keys)
- this_time = time.time()-t
- self.total_time += this_time*1000
- self.get_many += 1
- for key, value in results.iteritems():
- if value is None:
- self.misses += 1
- else:
- self.hits += 1
- self.calls.append((this_time, 'get_many', (keys,), self._get_func_info()))
-
-class CacheDebugPanel(DebugPanel):
- """
- Panel that displays the cache statistics.
- """
- name = 'Cache'
-
- def __init__(self, request):
- # This is hackish but to prevent threading issues
- # is somewhat needed
- if isinstance(cache.cache, CacheStatTracker):
- cache.cache.reset()
- self.cache = cache.cache
- else:
- self.cache = CacheStatTracker(cache.cache)
- cache.cache = self.cache
- super(CacheDebugPanel, self).__init__(request)
-
- def title(self):
- return 'Cache: %.2fms' % self.cache.total_time
-
- def url(self):
- return ''
-
- def content(self):
- context = dict(
- cache_calls = len(self.cache.calls),
- cache_time = self.cache.total_time,
- cache = self.cache,
- )
- return render_to_string('debug_toolbar/panels/cache.html', context)
\ No newline at end of file
+++ /dev/null
-from debug_toolbar.panels import DebugPanel
-from django.template.loader import render_to_string
-
-class HeaderDebugPanel(DebugPanel):
- """
- A panel to display HTTP headers.
- """
- name = 'Header'
- # List of headers we want to display
- header_filter = [
- 'CONTENT_TYPE',
- 'HTTP_ACCEPT',
- 'HTTP_ACCEPT_CHARSET',
- 'HTTP_ACCEPT_ENCODING',
- 'HTTP_ACCEPT_LANGUAGE',
- 'HTTP_CACHE_CONTROL',
- 'HTTP_CONNECTION',
- 'HTTP_HOST',
- 'HTTP_KEEP_ALIVE',
- 'HTTP_REFERER',
- 'HTTP_USER_AGENT',
- 'QUERY_STRING',
- 'REMOTE_ADDR',
- 'REMOTE_HOST',
- 'REQUEST_METHOD',
- 'SCRIPT_NAME',
- 'SERVER_NAME',
- 'SERVER_PORT',
- 'SERVER_PROTOCOL',
- 'SERVER_SOFTWARE',
- ]
- def title(self):
- return 'HTTP Headers'
-
- def url(self):
- return ''
-
- def content(self):
- context = {
- 'headers': dict([(k, self.request.META[k]) for k in self.header_filter if k in self.request.META]),
- }
- return render_to_string('debug_toolbar/panels/headers.html', context)
\ No newline at end of file
+++ /dev/null
-from debug_toolbar.panels import DebugPanel
-from django.template.loader import render_to_string
-
-class HttpVarsDebugPanel(DebugPanel):
- """
- A panel to display HTTP variables (POST/GET).
- """
- name = 'HttpVars'
- # List of headers we want to display
-
- def title(self):
- return 'HTTP Globals'
-
- def url(self):
- return ''
-
- def content(self):
- context = {
- 'get': [(k, self.request.GET.getlist(k)) for k in self.request.GET.iterkeys()],
- 'post': [(k, self.request.POST.getlist(k)) for k in self.request.POST.iterkeys()],
- 'session': [(k, self.request.session.get(k)) for k in self.request.session.iterkeys()],
- 'cookies': [(k, self.request.COOKIES.get(k)) for k in self.request.COOKIES.iterkeys()],
- }
- return render_to_string('debug_toolbar/panels/http_vars.html', context)
\ No newline at end of file
+++ /dev/null
-from debug_toolbar.panels import DebugPanel
-try: import cProfile as profile
-except ImportError: import profile
-import pstats
-from django.template.loader import render_to_string
-
-class ProfilerDebugPanel(DebugPanel):
- """
- Panel that displays the time a response took with cProfile output.
- """
- name = 'Profiler'
-
- def __init__(self, request):
- super(ProfilerDebugPanel, self).__init__(request)
-
- def process_response(self, request, response):
- stats = pstats.Stats(self.profiler)
- function_calls = []
- for func in stats.strip_dirs().sort_stats(1).fcn_list:
- current = []
- if stats.stats[func][0] != stats.stats[func][1]:
- current.append('%d/%d' % (stats.stats[func][1], stats.stats[func][0]))
- else:
- current.append(stats.stats[func][1])
- current.append(stats.stats[func][2]*1000)
- current.append(stats.stats[func][2]*1000/stats.stats[func][1])
- current.append(stats.stats[func][3]*1000)
- current.append(stats.stats[func][3]*1000/stats.stats[func][0])
- current.append(pstats.func_std_string(func))
- function_calls.append(current)
- self.stats = stats
- self.function_calls = function_calls
- return response
-
- def process_view(self, request, callback, callback_args, callback_kwargs):
- self.callback = callback
- self.profiler = profile.Profile()
- return self.profiler.runcall(callback, request, *callback_args, **callback_kwargs)
-
- def title(self):
- return 'View: %.2fms' % (float(self.stats.total_tt)*1000,)
-
- def url(self):
- return ''
-
- def content(self):
- context = {
- 'callback': self.callback.__name__,
- 'module': self.callback.__module__,
- 'stats': self.stats,
- 'function_calls': self.function_calls,
- }
- return render_to_string('debug_toolbar/panels/profiler.html', context)
\ No newline at end of file
+++ /dev/null
-from debug_toolbar.panels import DebugPanel
-from django.db import connection
-from django.db.backends import util
-from django.template.loader import render_to_string
-from django.shortcuts import render_to_response
-from django.http import HttpResponse
-from django.utils import simplejson
-from time import time
-
-class DatabaseStatTracker(util.CursorDebugWrapper):
- """Replacement for CursorDebugWrapper which stores additional information
- in `connection.queries`."""
- def execute(self, sql, params=()):
- start = time()
- try:
- return self.cursor.execute(sql, params)
- finally:
- stop = time()
- # We keep `sql` to maintain backwards compatibility
- self.db.queries.append({
- 'sql': self.db.ops.last_executed_query(self.cursor, sql, params),
- 'time': stop - start,
- 'raw_sql': sql,
- 'params': params,
- })
-
-util.CursorDebugWrapper = DatabaseStatTracker
-
-class SQLDebugPanel(DebugPanel):
- """
- Panel that displays information about the SQL queries run while processing the request.
- """
- name = 'SQL'
-
- def reformat_sql(self, sql):
- sql = sql.replace('`,`', '`, `')
- sql = sql.replace('` FROM `', '` \n FROM `')
- sql = sql.replace('` WHERE ', '` \n WHERE ')
- sql = sql.replace('`) WHERE ', '`) \n WHERE ')
- sql = sql.replace(' ORDER BY ', ' \n ORDER BY ')
- return sql
-
- def process_ajax(self, request):
- action = request.GET.get('op')
- if action == 'explain':
- # XXX: loop through each sql statement to output explain?
- sql = request.GET.get('sql', '').split(';')[0]
- if sql.lower().startswith('select'):
- if 'params' in request.GET:
- params = simplejson.loads(request.GET['params'])
- else:
- params = []
- cursor = connection.cursor()
- cursor.execute("EXPLAIN %s" % (sql,), params)
- response = cursor.fetchall()
- cursor.close()
- context = {'explain': response, 'sql': self.reformat_sql(sql), 'params': params}
- return render_to_response('debug_toolbar/panels/sql_explain.html', context)
- else:
- return HttpResponse('Invalid SQL', mimetype="text/plain", status_code=403)
-
- def process_request(self, request):
- self.queries_offset = len(connection.queries)
-
- def process_response(self, request, response):
- self.queries = connection.queries[self.queries_offset:]
- self.total_time = sum(map(lambda q: float(q['time'])*1000, self.queries))
- return response
-
- def title(self):
- return 'SQL: %.2fms (%d queries)' % (self.total_time, len(self.queries))
-
- def url(self):
- return ''
-
- def content(self):
- queries = [(q['time'], q['sql'], q['raw_sql'], simplejson.dumps(q['params'])) for q in sorted(self.queries, key=lambda x: x['time'])[::-1]]
- context = {'queries': queries}
- return render_to_string('debug_toolbar/panels/sql.html', context)
\ No newline at end of file
+++ /dev/null
-from debug_toolbar.panels import DebugPanel
-from django.conf import settings
-from django.dispatch import dispatcher
-from django.core.signals import request_started
-from django.test.signals import template_rendered
-from django.template.loader import render_to_string
-
-# Based on http://www.djangosnippets.org/snippets/766/
-from django.test.utils import instrumented_test_render
-from django.template import Template, Context
-if Template.render != instrumented_test_render:
- Template.original_render = Template.render
- Template.render = instrumented_test_render
-# MONSTER monkey-patch
-old_template_init = Template.__init__
-def new_template_init(self, template_string, origin=None, name='<Unknown Template>'):
- old_template_init(self, template_string, origin, name)
- self.origin = origin
-Template.__init__ = new_template_init
-
-class TemplatesDebugPanel(DebugPanel):
- """
- Panel that displays information about the SQL queries run while processing the request.
- """
- name = 'Templates'
-
- def __init__(self, *args, **kwargs):
- super(TemplatesDebugPanel, self).__init__(*args, **kwargs)
- self.templates_used = []
- self.contexts_used = []
- template_rendered.connect(self._storeRenderedTemplates)
-
- def _storeRenderedTemplates(self, **kwargs):
- template = kwargs.pop('template')
- if template:
- self.templates_used.append(template)
- context = kwargs.pop('context')
- if context:
- self.contexts_used.append(context)
-
- def process_response(self, request, response):
- self.templates = [
- (t.name, t.origin and t.origin.name or 'No origin')
- for t in self.templates_used
- ]
- return response
-
- def title(self):
- return 'Templates: %.2fms'
-
- def url(self):
- return ''
-
- def content(self):
- context = {
- 'templates': self.templates,
- 'template_dirs': settings.TEMPLATE_DIRS,
- }
-
- return render_to_string('debug_toolbar/panels/templates.html', context)
\ No newline at end of file
+++ /dev/null
-import time
-from debug_toolbar.panels import DebugPanel
-
-class TimerDebugPanel(DebugPanel):
- """
- Panel that displays the time a response took.
- """
- name = 'Timer'
-
- def __init__(self, request):
- super(TimerDebugPanel, self).__init__(request)
- self._start_time = time.time()
-
- def title(self):
- return 'Time: %0.2fms' % ((time.time() - self._start_time) * 1000)
-
- def url(self):
- return ''
-
- def content(self):
- return ''
+++ /dev/null
-import django
-from debug_toolbar.panels import DebugPanel
-
-class VersionDebugPanel(DebugPanel):
- """
- Panel that displays the Django version.
- """
- name = 'Version'
-
- def title(self):
- return 'Version: %s' % (django.get_version())
-
- def url(self):
- return ''
-
- def content(self):
- return ''
+++ /dev/null
-from django.conf import settings
-
-DEBUG_TOOLBAR_PANELS = getattr(settings, 'DEBUG_TOOLBAR_PANELS', (
- 'debug_toolbar.panels.version.VersionDebugPanel',
- 'debug_toolbar.panels.profiler.ProfilerDebugPanel',
- 'debug_toolbar.panels.sql.SQLDebugPanel',
- 'debug_toolbar.panels.cache.CacheDebugPanel',
- # 'debug_toolbar.panels.templates.TemplatesDebugPanel',
- 'debug_toolbar.panels.headers.HeaderDebugPanel',
- 'debug_toolbar.panels.http_vars.HttpVarsDebugPanel',
-))
+++ /dev/null
-<script type="text/javascript">
-var djDebugLastObj = null;
-function djDebugToggle(tag) {
- if (djDebugLastObj) {
- djDebugLastObj.className = '';
- document.getElementById(djDebugLastObj.getAttribute('rel')).style.display = 'none';
- }
- djDebugWindowClose();
- var obj = document.getElementById(tag.getAttribute('rel'));
- if (!obj) return;
- if (djDebugLastObj == tag) {
- djDebugLastObj = null;
- return;
- }
- if (obj.style.display != 'block') {
- obj.style.display = 'block';
- tag.className = 'active';
- djDebugLastObj = tag;
- }
-}
-function djDebugClose() {
- if (!djDebugLastObj) return;
- djDebugLastObj.className = '';
- document.getElementById(djDebugLastObj.getAttribute('rel')).style.display = 'none';
- djDebugLastObj = null;
-}
-function djDebugWindowHtml(text) {
- var obj = document.getElementById('djDebugWindow');
- var frame = obj.getElementsByTagName('div')[1];
- frame.innerHTML = text;
-}
-function djDebugWindow(url) {
- var obj = document.getElementById('djDebugWindow');
- djDebugWindowHtml('Loading request...');
- djDebugHttp.open('get', url, true);
-
- djDebugHttp.onreadystatechange = function() {
- if (djDebugHttp.readyState == 4) {
- // XXX: why does status return 0?
- if (djDebugHttp.status == 200 || djDebugHttp.status == 0) {
- djDebugWindowHtml(djDebugHttp.responseText);
- }
- else {
- djDebugWindowHtml('There was an error loading the document.');
- }
- }
- }
- djDebugHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
- try {
- djDebugHttp.send(null);
- }
- catch (ex) {
- djDebugWindowHtml('There was an error loading the document.');
- }
- obj.style.display = 'block';
-}
-function djDebugCreateXMLHttpRequest() {
- var http;
- if (window.XMLHttpRequest) { // Mozilla, Safari,...
- http = new XMLHttpRequest();
- if (http.overrideMimeType) {
- // set type accordingly to anticipated content type
- http.overrideMimeType('text/html');
- }
- }
- else if (window.ActiveXObject) { // IE
- try {
- http = new ActiveXObject("Msxml2.XMLHTTP");
- } catch (e) {
- try {
- http = new ActiveXObject("Microsoft.XMLHTTP");
- } catch (e) {}
- }
- }
- if (!http) {
- alert('Cannot create XMLHTTP instance');
- return false;
- }
- return http;
-}
-var djDebugHttp = djDebugCreateXMLHttpRequest();
-function djDebugWindowClose() {
- var obj = document.getElementById('djDebugWindow');
- obj.style.display = 'none';
-}
-function djDebugCloseAll() {
- djDebugClose();
- djDebugWindowClose();
-}
-function djDebugHide() {
- var obj = document.getElementById('djDebug');
- obj.style.display = 'none';
-}
-</script>
-<style type="text/css">
-#djDebug * { font: normal 12px Arial, sans-serif; margin: 0; padding: 0; float: none; position: static; border: 0; }
-#djDebugToolbar {
- height:22px;
- background:#244035;
- color:#90EF45;
- text-transform:lowercase;
- margin: 5px 0;
- z-index:100000000;
- border-top:1px solid #345447;
- border-bottom:1px solid #10211a;
-}
-#djDebugToolbar ul { margin: 0; padding: 0 10px; }
-#djDebugToolbar li { display: inline; height: 22px; float: left; }
-#djDebugToolbar li span,
-#djDebugToolbar li a { color: #FFE761; text-decoration: none; display: inline; width: auto; position: relative; float: none; margin: 0; height: 12px; line-height: 22px; padding: 4px 10px; border-left: 1px solid #345447; border-right: 1px solid #10211a; padding-right: 10px; }
-#djDebugToolbar li a:hover, #djDebugToolbar li.active a { color: #fff; background-color: #2e4d41; }
-#djDebugToolbar #djDebugButton span { border-left: 0; color: #fff; font-weight: bold; }
-#djDebugToolbar #djDebugHide { float: right; }
-#djDebugToolbar #djDebugHide a { border: 0; font-size: 93%; }
-#djDebug .panelContent {
- display:none;
- position:absolute;
- margin:0;
- padding:10px;
- top:43px;
- width:auto;
- left:10px;
- right:10px;
- bottom:10px;
- background:#244035;
- color:#fff;
- z-index:1000000;
- overflow:auto;
- border:1px solid #345447;
-}
-#djDebug .panelContent * { color: #fff; }
-#djDebug .panelContent a:hover { color: #FFE761; }
-#djDebug .panelContent table { width: 100%; }
-#djDebug .panelContent p { padding: 5px; }
-#djDebug .panelContent p, #djDebug .panelContent table,
-#djDebug .panelContent ul, #djDebug .panelContent dl,
-#djDebug .panelContent .title { margin: 5px 0; }
-#djDebug .panelContent dt, #djDebug .panelContent dd { display: block; }
-#djDebug .panelContent dt { font-weight: bold; width: 100px; clear: left; float: left; }
-#djDebug .panelContent dd { margin-left: 20px; margin-bottom: 5px; margin-left: 100px; }
-#djDebug .panelContent th, #djDebug td { padding: 5px; }
-#djDebug .panelContent td { background:#244035; }
-#djDebug .panelContent th { font-weight: bold; text-align: left; background: transparent; color: #fff; }
-#djDebug .panelContent thead th { border-bottom: 1px solid #2e4d41; color: #FFE761; }
-#djDebug .panelContent .row2 td { background:#2e4d41; }
-#djDebugWindow { z-index: 20000000; }
-#djDebug .panelContent .title { font-weight: bold; font-size: 15px; color: #90EF45; }
-#djDebug .panelContent .title a { float: right; font-weight: bold; font-size: 10px; }
-#djDebug .panelContent .title .close { float: right; font-weight: bold; margin-left: 15px; }
-</style>
-
-<div id="djDebug">
- <div id="djDebugToolbar">
- <ul id="djDebugPanelList">
- <li id="djDebugButton"><span>Django Debug</span></li>
- {% for panel in panels %}
- <li rel="{{ panel.dom_id }}">
- {% if panel.content %}
- <a href="{{ panel.url|default:"#" }}" onclick="djDebugToggle(this.parentNode)" title="{{ panel.title }}" class="{{ panel.dom_id }}">{{ panel.title }}</a>
- {% else %}
- <span>{{ panel.title }}</span>
- {% endif %}
- </li>
- {% endfor %}
- <li id="djDebugHide"><a href="javascript:djDebugHide();">Hide Debug Toolbar</a></li>
- </ul>
- </div>
- {% for panel in panels %}
- {% with panel.content as content %}
- {% if content %}
- <div id="{{ panel.dom_id }}" class="panelContent">
- <div class="title">
- <a href="javascript:djDebugCloseAll()" class="close">Close</a>
- <!-- <h1>{{ panel.title }}</h1> -->
- </div>
- <div class="content">
- {{ content|safe }}
- </div>
- </div>
- {% endif %}
- {% endwith %}
- {% endfor %}
- <div id="djDebugWindow" class="panelContent">
- <div class="title">
- <a href="javascript:djDebugCloseAll()" class="close">Close</a>
- <a href="javascript:djDebugWindowClose();" class="close">Back</a>
- </div>
- <div class="content">
- </div>
- </div>
-</div>
+++ /dev/null
-<div class="title">
- Cache Usage
-</div>
-<table>
- <colgroup>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- </colgroup>
- <tr>
- <th>Total Calls</th>
- <td>{{ cache_calls }}</td>
- <th>Total Time</th>
- <td>{{ cache_time }}ms</td>
- <th>Hits</th>
- <td>{{ cache.hits }}</td>
- <th>Misses</th>
- <td>{{ cache.misses }}</td>
- </tr>
- <tr>
- <th>gets</th>
- <td>{{ cache.gets }}</td>
- <th>sets</th>
- <td>{{ cache.sets }}</td>
- <th>deletes</th>
- <td>{{ cache.deletes }}</td>
- <th>get_many</th>
- <td>{{ cache.get_many }}</td>
- </tr>
-</table>
-{% if cache.calls %}
-<div class="title">
- Breakdown
-</div>
-<table>
- <thead>
- <tr>
- <th>Time (ms)</th>
- <th>Type</th>
- <th>Parameters</th>
- <th>Function</th>
- </tr>
- </thead>
- <tbody>
- {% for query in cache.calls %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ query.0|floatformat:"4" }}</td>
- <td>{{ query.1|escape }}</td>
- <td>{{ query.2|escape }}</td>
- <td>{{ query.3.0 }}:{{ query.3.1 }}({{ query.3.2|escape }}); {{ query.3.3.0|escape }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% endif %}
\ No newline at end of file
+++ /dev/null
-<div class="title">
- Request Headers
-</div>
-<table>
- <thead>
- <tr>
- <th>Key</th>
- <th>Value</th>
- </tr>
- </thead>
- <tbody>
- {% for key, value in headers.iteritems %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ key|escape }}</td>
- <td>{{ value|escape }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
\ No newline at end of file
+++ /dev/null
-<div class="title">request.GET</div>
-{% if get %}
-<table>
- <colgroup>
- <col style="width:20%"/>
- <col/>
- </colgroup>
- <thead>
- <tr>
- <th>Key</th>
- <th>Value</th>
- </tr>
- </thead>
- <tbody>
- {% for key, value in get %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ key|escape }}</td>
- <td>{{ value|join:", "|escape }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% else %}
-<p>No GET variables.</p>
-{% endif %}
-<div class="title">request.POST</div>
-{% if post %}
-<table>
- <colgroup>
- <col style="width:20%"/>
- <col/>
- </colgroup>
- <thead>
- <tr>
- <th>Key</th>
- <th>Value</th>
- </tr>
- </thead>
- <tbody>
- {% for key, value in post %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ key|escape }}</td>
- <td>{{ value|join:", "|escape }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% else %}
-<p>No POST variables.</p>
-{% endif %}
-<div class="title">request.session</div>
-{% if session %}
-<table>
- <colgroup>
- <col style="width:20%"/>
- <col/>
- </colgroup>
- <thead>
- <tr>
- <th>Key</th>
- <th>Value</th>
- </tr>
- </thead>
- <tbody>
- {% for key, value in session %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ key|escape }}</td>
- <td>{{ value|escape }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% else %}
-<p>No SESSION variables.</p>
-{% endif %}
-<div class="title">request.COOKIES</div>
-{% if cookies %}
-<table>
- <colgroup>
- <col style="width:20%"/>
- <col/>
- </colgroup>
- <thead>
- <tr>
- <th>Key</th>
- <th>Value</th>
- </tr>
- </thead>
- <tbody>
- {% for key, value in cookies %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ key|escape }}</td>
- <td>{{ value|escape }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% else %}
-<p>No COOKIES variables.</p>
-{% endif %}
\ No newline at end of file
+++ /dev/null
-<div class="title">
- Profile Output
-</div>
-<p>`profile` module output for the view `{{ module|escape }}.{{ callback|escape }}`</p>
-<table>
- <thead>
- <tr>
- <th>Calls</th>
- <th>Total Time (ms)</th>
- <th>Per Call (ms)</th>
- <th>Cumulative Time (ms)</th>
- <th>Per Call (ms)</th>
- <th>Function</th>
- </tr>
- </thead>
- <tbody>
- {% for row in function_calls %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ row.0 }}</td>
- <td>{{ row.1|floatformat:"4" }}</td>
- <td>{{ row.2|floatformat:"4" }}</td>
- <td>{{ row.3|floatformat:"4" }}</td>
- <td>{{ row.4|floatformat:"4" }}</td>
- <td>{{ row.5|escape }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
\ No newline at end of file
+++ /dev/null
-<div class="title">
- SQL Queries
-</div>
-<table>
- <thead>
- <tr>
- <th>Time (ms)</th>
- <th>Query</th>
- </tr>
- </thead>
- <tbody>
- {% for query in queries %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ query.0|floatformat:"4" }}</td>
- <td><a href="javascript:djDebugWindow('?djDebug=SQL&op=explain&sql={{ query.2|urlencode }}&params={{ query.3|urlencode }}');">{{ query.1|escape }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
\ No newline at end of file
+++ /dev/null
-<div class="title">SQL Explain</div>
-<dl>
- <dt>Query:</dt>
- <dd style="white-space:pre-wrap;">{{ sql|escape|linebreaksbr }}</dd>
- <dt>Parameters:</dt>
- <dd>{{ params|join:", "|escape }}</dd>
-</dl>
-<table>
- <thead>
- <tr>
- <th>ID</th>
- <th>Select Type</th>
- <th>Table</th>
- <th>Type</th>
- <th>Possible Keys</th>
- <th>Key</th>
- <th>Ken Length</th>
- <th>Ref</th>
- <th>Rows</th>
- <th>Extra</th>
- </tr>
- </thead>
- <tbody>
- {% for row in explain %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ row.0|escape }}</td>
- <td>{{ row.1|escape }}</td>
- <td>{{ row.2|escape }}</td>
- <td>{{ row.3|escape }}</td>
- <td>{{ row.4|escape }}</td>
- <td>{{ row.5|escape }}</td>
- <td>{{ row.6|escape }}</td>
- <td>{{ row.7|escape }}</td>
- <td>{{ row.8|escape }}</td>
- <td>{{ row.9|escape }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
\ No newline at end of file
+++ /dev/null
-<div class="title">
- Templates
-</div>
-<table>
- <thead>
- <tr>
- <th>Time (ms)</th>
- <th>Template</th>
- </tr>
- </thead>
- <tbody>
- {% for template in templates %}
- <tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ template }}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
\ No newline at end of file
+++ /dev/null
-"""
-The main DebugToolbar class that loads and renders the Toolbar.
-"""
-from django.template.loader import render_to_string
-from debug_toolbar.settings import DEBUG_TOOLBAR_PANELS
-
-class DebugToolbar(object):
-
- def __init__(self, request):
- self.request = request
- self.panels = []
- self.panel_list = []
- self.content_list = []
-
- def load_panels(self):
- """
- Populate debug panel lists from settings.DEBUG_TOOLBAR_PANELS.
- """
- from django.conf import settings
- from django.core import exceptions
-
- for panel_path in DEBUG_TOOLBAR_PANELS:
- try:
- dot = panel_path.rindex('.')
- except ValueError:
- raise exceptions.ImproperlyConfigured, '%s isn\'t a debug panel module' % panel_path
- panel_module, panel_classname = panel_path[:dot], panel_path[dot+1:]
- try:
- mod = __import__(panel_module, {}, {}, [''])
- except ImportError, e:
- raise exceptions.ImproperlyConfigured, 'Error importing debug panel %s: "%s"' % (panel_module, e)
- try:
- panel_class = getattr(mod, panel_classname)
- except AttributeError:
- raise exceptions.ImproperlyConfigured, 'Toolbar Panel module "%s" does not define a "%s" class' % (panel_module, panel_classname)
-
- try:
- panel_instance = panel_class(self.request)
- except:
- raise
- continue # Some problem loading panel
-
- self.panels.append(panel_instance)
-
- def render_toolbar(self):
- """
- Renders the overall Toolbar with panels inside.
- """
- return render_to_string('debug_toolbar/base.html', {'panels': self.panels})
'django.core.context_processors.request',
)
-MIDDLEWARE_CLASSES = (
+MIDDLEWARE_CLASSES = [
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.doc.XViewMiddleware',
- 'debug_toolbar.middleware.DebugToolbarMiddleware',
'pagination.middleware.PaginationMiddleware',
-)
-
-DEBUG_TOOLBAR_PANELS = (
- 'debug_toolbar.panels.version.VersionDebugPanel',
- 'debug_toolbar.panels.sql.SQLDebugPanel',
- 'debug_toolbar.panels.timer.TimerDebugPanel',
- 'debug_toolbar.panels.headers.HeaderDebugPanel',
-)
+]
-INTERNAL_IPS = ('127.0.0.1', )
+# If DEBUG is enabled add query log to bottom of every template
+if DEBUG:
+ MIDDLEWARE_CLASSES.append('middleware.ProfileMiddleware')
ROOT_URLCONF = 'urls'
'pagination',
'chunks',
'compress',
- 'debug_toolbar',
'catalogue',
)