diff options
| author | Aymeric Augustin | 2013-11-24 17:13:11 +0100 | 
|---|---|---|
| committer | Aymeric Augustin | 2013-11-24 17:15:59 +0100 | 
| commit | f52f266c691fd8bb80b21ab2a983118b914c04fa (patch) | |
| tree | 3cafd92796aae91e63abc3958ab1642745b6cfd8 | |
| parent | c92f710125218755c275ae98581a4305e57fd3fa (diff) | |
| download | django-debug-toolbar-f52f266c691fd8bb80b21ab2a983118b914c04fa.tar.bz2 | |
Clean up and document the Panel API.
| -rw-r--r-- | debug_toolbar/panels/__init__.py | 141 | ||||
| -rw-r--r-- | docs/conf.py | 3 | ||||
| -rw-r--r-- | docs/panels.rst | 40 | 
3 files changed, 155 insertions, 29 deletions
| diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py index d1a90d0..39c9d80 100644 --- a/debug_toolbar/panels/__init__.py +++ b/debug_toolbar/panels/__init__.py @@ -9,28 +9,17 @@ class Panel(object):      """      Base class for panels.      """ -    # name = 'Base' -    # template = 'debug_toolbar/panels/base.html' - -    # If content returns something, set to True in subclass -    has_content = False      # We'll maintain a local context instance so we can expose our template -    # context variables to panels which need them: +    # context variables to panels which need them. (But see issue #450.)      context = {} -    # Panel methods +    # Private panel methods      def __init__(self, toolbar, context={}):          self.toolbar = toolbar          self.context.update(context) -    def content(self): -        if self.has_content: -            context = self.context.copy() -            context.update(self.get_stats()) -            return render_to_string(self.template, context) -      @property      def panel_id(self):          return self.__class__.__name__ @@ -39,52 +28,146 @@ class Panel(object):      def enabled(self):          return self.toolbar.request.COOKIES.get('djdt' + self.panel_id, 'on') == 'on' -    # URLs for panel-specific views - -    @classmethod -    def get_urls(cls): -        return [] - -    # Titles and subtitles +    # Titles and content +    @property      def nav_title(self): -        """Title showing in sidebar""" -        raise NotImplementedError +        """ +        Title shown in the side bar. Defaults to :attr:`title`. +        """ +        return self.title +    @property      def nav_subtitle(self): -        """Subtitle showing under title in sidebar""" +        """ +        Subtitle shown in the side bar. Defaults to the empty string. +        """          return '' +    @property +    def has_content(self): +        """ +        ``True`` if the panel can be displayed in full screen, ``False`` if +        it's only shown in the side bar. Defaults to ``True``. +        """ +        return True + +    @property      def title(self): -        """Title showing in panel""" +        """ +        Title shown in the panel when it's displayed in full screen. + +        Mandatory, unless the panel sets :attr:`has_content` to ``False``. +        """ +        raise NotImplementedError + +    @property +    def template(self): +        """ +        Template used to render :attr:`content`. + +        Mandatory, unless the panel sets :attr:`has_content` to ``False`` or +        overrides `attr`:content`. +        """          raise NotImplementedError +    @property +    def content(self): +        """ +        Content of the panel when it's displayed in full screen. + +        By default this renders the template defined by :attr:`template`. +        Statistics stored with :meth:`record_stats` are available in the +        template's context. +        """ +        if self.has_content: +            context = self.context.copy() +            context.update(self.get_stats()) +            return render_to_string(self.template, context) + +    # URLs for panel-specific views + +    @classmethod +    def get_urls(cls): +        """ +        Return URLpatterns, if the panel has its own views. +        """ +        return [] +      # Enable and disable (expensive) instrumentation, must be idempotent      def enable_instrumentation(self): -        pass +        """ +        Enable instrumentation to gather data for this panel. + +        This usually means monkey-patching (!) or registering signal +        receivers. Any instrumentation with a non-negligible effect on +        performance should be installed by this method rather than at import +        time. + +        Unless the toolbar or this panel is disabled, this method will be +        called early in :class:`DebugToolbarMiddleware.process_request`. It +        should be idempotent. +        """      def disable_instrumentation(self): -        pass +        """ +        Disable instrumentation to gather data for this panel. + +        This is the opposite of :meth:`enable_instrumentation`. + +        Unless the toolbar or this panel is disabled, this method will be +        called late in :class:`DebugToolbarMiddleware.process_response`. It +        should be idempotent. +        """      # Store and retrieve stats (shared between panels for no good reason)      def record_stats(self, stats): +        """ +        Store data gathered by the panel. ``stats`` is a :class:`dict`. + +        Each call to ``record_stats`` updates the statistics dictionary. +        """          self.toolbar.stats.setdefault(self.panel_id, {}).update(stats)      def get_stats(self): +        """ +        Access data stored by the panel. Returns a :class:`dict`. +        """          return self.toolbar.stats.get(self.panel_id, {})      # Standard middleware methods      def process_request(self, request): -        pass +        """ +        Like process_request_ in Django's middleware. + +        Write panel logic related to the request there. Save data with +        :meth:`record_stats`. + +        .. _process_request: https://docs.djangoproject.com/en/stable/topics/http/middleware/#process-request +        """      def process_view(self, request, view_func, view_args, view_kwargs): -        pass +        """ +        Like process_view_ in Django's middleware. + +        Write panel logic related to the view there. Save data with +        :meth:`record_stats`. + +        .. _process_view: https://docs.djangoproject.com/en/stable/topics/http/middleware/#process-request +        """      def process_response(self, request, response): -        pass +        """ +        Like process_response_ in Django's middleware. + +        Write panel logic related to the response there. Post-process data +        gathered while the view executed. Save data with :meth:`record_stats`. + +        .. _process_response: https://docs.djangoproject.com/en/stable/topics/http/middleware/#process-request +        """  # Backward-compatibility for 1.0, remove in 2.0. diff --git a/docs/conf.py b/docs/conf.py index c2fcade..abde59b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,6 +15,9 @@  import sys  import os +os.environ['DJANGO_SETTINGS_MODULE'] = 'example.settings' +sys.path.append(os.path.dirname(os.path.dirname(__file__))) +  # If extensions (or modules to document with autodoc) are in another directory,  # add these directories to sys.path here. If the directory is relative to the  # documentation root, use os.path.abspath to make it absolute, like shown here. diff --git a/docs/panels.rst b/docs/panels.rst index 39ddf7f..c766780 100644 --- a/docs/panels.rst +++ b/docs/panels.rst @@ -212,3 +212,43 @@ URL: https://github.com/playfire/django-debug-toolbar-user-panel  Path: ``debug_toolbar_user_panel.panels.UserPanel``  Easily switch between logged in users, see properties of current user. + +API for third-party panels +-------------------------- + +Third-party panels must subclass :class:`~debug_toolbar.panels.Panel`, +according to the public API described below. Unless noted otherwise, all +methods are optional. + +Panels can ship their own templates, static files and views. They're no public +CSS or JavaScript API at this time, but they can assume jQuery is available. + +.. autoclass:: debug_toolbar.panels.Panel(*args, **kwargs) + +    .. autoattribute:: debug_toolbar.panels.Panel.nav_title + +    .. autoattribute:: debug_toolbar.panels.Panel.nav_subtitle + +    .. autoattribute:: debug_toolbar.panels.Panel.has_content + +    .. autoattribute:: debug_toolbar.panels.Panel.title + +    .. autoattribute:: debug_toolbar.panels.Panel.template + +    .. autoattribute:: debug_toolbar.panels.Panel.content + +    .. automethod:: debug_toolbar.panels.Panel.get_urls + +    .. automethod:: debug_toolbar.panels.Panel.enable_instrumentation + +    .. automethod:: debug_toolbar.panels.Panel.disable_instrumentation + +    .. automethod:: debug_toolbar.panels.Panel.record_stats + +    .. automethod:: debug_toolbar.panels.Panel.get_stats + +    .. automethod:: debug_toolbar.panels.Panel.process_request + +    .. automethod:: debug_toolbar.panels.Panel.process_view + +    .. automethod:: debug_toolbar.panels.Panel.process_response | 
