""" The main DebugToolbar class that loads and renders the Toolbar. """ from __future__ import unicode_literals from django.conf import settings from django.template.loader import render_to_string from django.utils.datastructures import SortedDict from django.utils.importlib import import_module from debug_toolbar.utils.settings import CONFIG class DebugToolbar(object): def __init__(self, request): self.request = request self._panels = SortedDict() base_url = self.request.META.get('SCRIPT_NAME', '') self.config = { 'MEDIA_URL': '%s/__debug__/m/' % base_url, } self.config.update(CONFIG) self.template_context = { 'BASE_URL': base_url, # for backwards compatibility 'DEBUG_TOOLBAR_MEDIA_URL': self.config['MEDIA_URL'], 'STATIC_URL': settings.STATIC_URL, 'TOOLBAR_ROOT_TAG_ATTRS': self.config['ROOT_TAG_ATTRS'], } self.load_panels() self.stats = {} def _get_panels(self): return list(self._panels.values()) panels = property(_get_panels) def get_panel(self, cls): return self._panels[cls] def load_panels(self): """ Populate debug panels """ global panel_classes for panel_class in panel_classes: panel_instance = panel_class(self, context=self.template_context) self._panels[panel_class] = panel_instance def render_toolbar(self): """ Renders the overall Toolbar with panels inside. """ context = self.template_context.copy() context.update({ 'panels': self.panels, 'toolbar_id': save_toolbar(self), }) return render_to_string('debug_toolbar/base.html', context) panel_classes = [] def load_panel_classes(): from django.conf import settings from django.core.exceptions import ImproperlyConfigured # Check if settings has a DEBUG_TOOLBAR_PANELS, otherwise use default panels = getattr(settings, 'DEBUG_TOOLBAR_PANELS', ( 'debug_toolbar.panels.version.VersionDebugPanel', 'debug_toolbar.panels.timer.TimerDebugPanel', 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel', 'debug_toolbar.panels.headers.HeaderDebugPanel', 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel', 'debug_toolbar.panels.sql.SQLDebugPanel', 'debug_toolbar.panels.template.TemplateDebugPanel', 'debug_toolbar.panels.cache.CacheDebugPanel', 'debug_toolbar.panels.signals.SignalDebugPanel', 'debug_toolbar.panels.logger.LoggingPanel', )) for panel_path in panels: try: dot = panel_path.rindex('.') except ValueError: raise ImproperlyConfigured( "%s isn't a debug panel module" % panel_path) panel_module, panel_classname = panel_path[:dot], panel_path[dot + 1:] try: mod = import_module(panel_module) except ImportError as e: raise ImproperlyConfigured( 'Error importing debug panel %s: "%s"' % (panel_module, e)) try: panel_class = getattr(mod, panel_classname) except AttributeError: raise ImproperlyConfigured( 'Toolbar Panel module "%s" does not define a "%s" class' % (panel_module, panel_classname)) panel_classes.append(panel_class) toolbar_counter = 0 toolbar_maxsize = 10 # keep data for the last 10 requests toolbar_results = SortedDict() def save_toolbar(toolbar): global toolbar_counter, toolbar_results toolbar_counter += 1 toolbar_results[toolbar_counter] = toolbar for _ in range(len(toolbar_results) - toolbar_maxsize): # When we drop support for Python 2.6 and switch to # collections.OrderedDict, use popitem(last=False). del toolbar_results[toolbar_results.keyOrder[0]] return toolbar_counter def get_saved_toolbar(toolbar_id): return toolbar_results.get(toolbar_id)