diff options
| author | Alex Gaynor | 2009-05-27 19:17:24 -0700 | 
|---|---|---|
| committer | Rob Hudson | 2009-05-27 19:18:28 -0700 | 
| commit | 1956ee540c75f9d4226f0352df5b06aae5c02703 (patch) | |
| tree | 40cd6981c02dc58e0197586846f256cac07bb745 | |
| parent | 08b6a97d759e9808962cafd5a5ef3bab3642ccdb (diff) | |
| download | django-debug-toolbar-1956ee540c75f9d4226f0352df5b06aae5c02703.tar.bz2 | |
Adding a signals panel to display list of signals and their providing arguments
and receivers.  Thanks Alex Gaynor!
Signed-off-by: Rob Hudson <rob@cogit8.org>
| -rw-r--r-- | README.rst | 8 | ||||
| -rw-r--r-- | debug_toolbar/panels/signals.py | 73 | ||||
| -rw-r--r-- | debug_toolbar/panels/sql.py | 2 | ||||
| -rw-r--r-- | debug_toolbar/templates/debug_toolbar/panels/signals.html | 19 | ||||
| -rw-r--r-- | debug_toolbar/toolbar/loader.py | 1 | 
5 files changed, 101 insertions, 2 deletions
| @@ -15,6 +15,7 @@ Currently, the following panels have been written and are working:  - GET/POST/cookie/session variable display  - Templates and context used, and their template paths  - SQL queries including time to execute and links to EXPLAIN each query +- List of signals, their args and receivers  - Logging output via Python's built-in logging module  If you have ideas for other panels please let us know. @@ -50,7 +51,7 @@ Installation  #. Add `debug_toolbar` to your `INSTALLED_APPS` setting so Django can find the     template files associated with the Debug Toolbar. -    +     Alternatively, add the path to the debug toolbar templates     (``'path/to/debug_toolbar/templates'`` to your ``TEMPLATE_DIRS`` setting.) @@ -72,6 +73,7 @@ The debug toolbar has two settings that can be set in `settings.py`:  	    'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',  	    'debug_toolbar.panels.template.TemplateDebugPanel',  	    'debug_toolbar.panels.sql.SQLDebugPanel', +	    'debug_toolbar.panels.signals.SignalDebugPanel',  	    'debug_toolbar.panels.logger.LoggingPanel',  	) @@ -96,6 +98,9 @@ The debug toolbar has two settings that can be set in `settings.py`:       provide your own method for displaying the toolbar which contains your       custom logic.  This method should return True or False. +   * `EXTRA_SIGNALS`: An array of custom signals that might be in your project, +     defined as the python path to the signal. +     Example configuration::  	def custom_show_toolbar(request): @@ -104,6 +109,7 @@ The debug toolbar has two settings that can be set in `settings.py`:  	DEBUG_TOOLBAR_CONFIG = {  	    'INTERCEPT_REDIRECTS': False,  	    'SHOW_TOOLBAR_CALLBACK': custom_show_toolbar, +	    'EXTRA_SIGNALS': ['myproject.signals.MySignal'],  	}  TODOs and BUGS diff --git a/debug_toolbar/panels/signals.py b/debug_toolbar/panels/signals.py new file mode 100644 index 0000000..0a75282 --- /dev/null +++ b/debug_toolbar/panels/signals.py @@ -0,0 +1,73 @@ +import sys + +from django.conf import settings +from django.core.signals import request_started, request_finished, \ +    got_request_exception +from django.db.backends.signals import connection_created +from django.db.models.signals import class_prepared, pre_init, post_init, \ +    pre_save, post_save, pre_delete, post_delete, post_syncdb +from django.dispatch.dispatcher import WEAKREF_TYPES +from django.template.loader import render_to_string + +from debug_toolbar.panels import DebugPanel + +class SignalDebugPanel(DebugPanel): +    name = "Signals" +    has_content = True + +    SIGNALS = { +        'request_started': request_started, +        'request_finished': request_finished, +        'got_request_exception': got_request_exception, +        'connection_created': connection_created, +        'class_prepared': class_prepared, +        'pre_init': pre_init, +        'post_init': post_init, +        'pre_save': pre_save, +        'post_save': post_save, +        'pre_delete': pre_delete, +        'post_delete': post_delete, +        'post_syncdb': post_syncdb, +    } + +    def title(self): +        return "Signals" + +    def url(self): +        return '' + +    def signals(self): +        signals = self.SIGNALS.copy() +        if hasattr(settings, 'DEBUG_TOOLBAR_CONFIG'): +            extra_signals = settings.DEBUG_TOOLBAR_CONFIG.get('EXTRA_SIGNALS', []) +        else: +            extra_signals = [] +        for signal in extra_signals: +            parts = signal.split('.') +            path = '.'.join(parts[:-1]) +            __import__(path) +            signals[parts[-1]] = getattr(sys.modules[path], parts[-1]) +        return signals +    signals = property(signals) + +    def content(self): +        signals = [] +        keys = self.signals.keys() +        keys.sort() +        for name in keys: +            signal = self.signals[name] +            receivers = [] +            for (receiverkey, r_senderkey), receiver in signal.receivers: +                if isinstance(receiver, WEAKREF_TYPES): +                    receiver = receiver() +                if receiver is None: +                    continue +                if getattr(receiver, 'im_self', None) is not None: +                    text = "method %s on %s object" % (receiver.__name__, receiver.im_self.__class__.__name__) +                elif getattr(receiver, 'im_class', None) is not None: +                    text = "method %s on %s" % (receiver.__name__, receiver.im_class.__name__) +                else: +                    text = "function %s" % receiver.__name__ +                receivers.append(text) +            signals.append((name, signal, receivers)) +        return render_to_string('debug_toolbar/panels/signals.html', {'signals': signals}) diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index 8934fb3..d3ac7f3 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -98,7 +98,7 @@ class SQLDebugPanel(DebugPanel):          return render_to_string('debug_toolbar/panels/sql.html', context)  def reformat_sql(sql): -    sql = sql.replace('`,`', '`, `') +    sql = sql.replace(',', ', ')      sql = sql.replace('SELECT ', 'SELECT\n\t')      sql = sql.replace(' FROM ', '\nFROM\n\t')      sql = sql.replace(' WHERE ', '\nWHERE\n\t') diff --git a/debug_toolbar/templates/debug_toolbar/panels/signals.html b/debug_toolbar/templates/debug_toolbar/panels/signals.html new file mode 100644 index 0000000..e9a189e --- /dev/null +++ b/debug_toolbar/templates/debug_toolbar/panels/signals.html @@ -0,0 +1,19 @@ +<h3>Signals</h3> +<table> +    <thead> +        <tr> +            <th>Signal</th> +            <th>Providing Args</th> +            <th>Receivers</th> +        </tr> +    </thead> +    <tbody> +        {% for name, signal, receivers in signals %} +            <tr class="{% cycle 'djDebugOdd' 'djDebugEven' %}"> +                <td>{{ name|escape }}</td> +                <td>{{ signal.providing_args|join:", " }}</td> +                <td>{{ receivers|join:", " }}</td> +            </tr> +        {% endfor %} +    </tbody> +</table> diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index 39fb4c6..c7f999e 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -21,6 +21,7 @@ class DebugToolbar(object):              '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',          )          self.load_panels() | 
