@@ -9,28 +9,17 @@ class Panel(object):
9
9
"""
10
10
Base class for panels.
11
11
"""
12
- # name = 'Base'
13
- # template = 'debug_toolbar/panels/base.html'
14
-
15
- # If content returns something, set to True in subclass
16
- has_content = False
17
12
18
13
# We'll maintain a local context instance so we can expose our template
19
- # context variables to panels which need them:
14
+ # context variables to panels which need them. (But see issue #450.)
20
15
context = {}
21
16
22
- # Panel methods
17
+ # Private panel methods
23
18
24
19
def __init__ (self , toolbar , context = {}):
25
20
self .toolbar = toolbar
26
21
self .context .update (context )
27
22
28
- def content (self ):
29
- if self .has_content :
30
- context = self .context .copy ()
31
- context .update (self .get_stats ())
32
- return render_to_string (self .template , context )
33
-
34
23
@property
35
24
def panel_id (self ):
36
25
return self .__class__ .__name__
@@ -39,52 +28,146 @@ def panel_id(self):
39
28
def enabled (self ):
40
29
return self .toolbar .request .COOKIES .get ('djdt' + self .panel_id , 'on' ) == 'on'
41
30
42
- # URLs for panel-specific views
43
-
44
- @classmethod
45
- def get_urls (cls ):
46
- return []
47
-
48
- # Titles and subtitles
31
+ # Titles and content
49
32
33
+ @property
50
34
def nav_title (self ):
51
- """Title showing in sidebar"""
52
- raise NotImplementedError
35
+ """
36
+ Title shown in the side bar. Defaults to :attr:`title`.
37
+ """
38
+ return self .title
53
39
40
+ @property
54
41
def nav_subtitle (self ):
55
- """Subtitle showing under title in sidebar"""
42
+ """
43
+ Subtitle shown in the side bar. Defaults to the empty string.
44
+ """
56
45
return ''
57
46
47
+ @property
48
+ def has_content (self ):
49
+ """
50
+ ``True`` if the panel can be displayed in full screen, ``False`` if
51
+ it's only shown in the side bar. Defaults to ``True``.
52
+ """
53
+ return True
54
+
55
+ @property
58
56
def title (self ):
59
- """Title showing in panel"""
57
+ """
58
+ Title shown in the panel when it's displayed in full screen.
59
+
60
+ Mandatory, unless the panel sets :attr:`has_content` to ``False``.
61
+ """
62
+ raise NotImplementedError
63
+
64
+ @property
65
+ def template (self ):
66
+ """
67
+ Template used to render :attr:`content`.
68
+
69
+ Mandatory, unless the panel sets :attr:`has_content` to ``False`` or
70
+ overrides `attr`:content`.
71
+ """
60
72
raise NotImplementedError
61
73
74
+ @property
75
+ def content (self ):
76
+ """
77
+ Content of the panel when it's displayed in full screen.
78
+
79
+ By default this renders the template defined by :attr:`template`.
80
+ Statistics stored with :meth:`record_stats` are available in the
81
+ template's context.
82
+ """
83
+ if self .has_content :
84
+ context = self .context .copy ()
85
+ context .update (self .get_stats ())
86
+ return render_to_string (self .template , context )
87
+
88
+ # URLs for panel-specific views
89
+
90
+ @classmethod
91
+ def get_urls (cls ):
92
+ """
93
+ Return URLpatterns, if the panel has its own views.
94
+ """
95
+ return []
96
+
62
97
# Enable and disable (expensive) instrumentation, must be idempotent
63
98
64
99
def enable_instrumentation (self ):
65
- pass
100
+ """
101
+ Enable instrumentation to gather data for this panel.
102
+
103
+ This usually means monkey-patching (!) or registering signal
104
+ receivers. Any instrumentation with a non-negligible effect on
105
+ performance should be installed by this method rather than at import
106
+ time.
107
+
108
+ Unless the toolbar or this panel is disabled, this method will be
109
+ called early in :class:`DebugToolbarMiddleware.process_request`. It
110
+ should be idempotent.
111
+ """
66
112
67
113
def disable_instrumentation (self ):
68
- pass
114
+ """
115
+ Disable instrumentation to gather data for this panel.
116
+
117
+ This is the opposite of :meth:`enable_instrumentation`.
118
+
119
+ Unless the toolbar or this panel is disabled, this method will be
120
+ called late in :class:`DebugToolbarMiddleware.process_response`. It
121
+ should be idempotent.
122
+ """
69
123
70
124
# Store and retrieve stats (shared between panels for no good reason)
71
125
72
126
def record_stats (self , stats ):
127
+ """
128
+ Store data gathered by the panel. ``stats`` is a :class:`dict`.
129
+
130
+ Each call to ``record_stats`` updates the statistics dictionary.
131
+ """
73
132
self .toolbar .stats .setdefault (self .panel_id , {}).update (stats )
74
133
75
134
def get_stats (self ):
135
+ """
136
+ Access data stored by the panel. Returns a :class:`dict`.
137
+ """
76
138
return self .toolbar .stats .get (self .panel_id , {})
77
139
78
140
# Standard middleware methods
79
141
80
142
def process_request (self , request ):
81
- pass
143
+ """
144
+ Like process_request_ in Django's middleware.
145
+
146
+ Write panel logic related to the request there. Save data with
147
+ :meth:`record_stats`.
148
+
149
+ .. _process_request: https://docs.djangoproject.com/en/stable/topics/http/middleware/#process-request
150
+ """
82
151
83
152
def process_view (self , request , view_func , view_args , view_kwargs ):
84
- pass
153
+ """
154
+ Like process_view_ in Django's middleware.
155
+
156
+ Write panel logic related to the view there. Save data with
157
+ :meth:`record_stats`.
158
+
159
+ .. _process_view: https://docs.djangoproject.com/en/stable/topics/http/middleware/#process-request
160
+ """
85
161
86
162
def process_response (self , request , response ):
87
- pass
163
+ """
164
+ Like process_response_ in Django's middleware.
165
+
166
+ Write panel logic related to the response there. Post-process data
167
+ gathered while the view executed. Save data with :meth:`record_stats`.
168
+
169
+ .. _process_response: https://docs.djangoproject.com/en/stable/topics/http/middleware/#process-request
170
+ """
88
171
89
172
90
173
# Backward-compatibility for 1.0, remove in 2.0.
0 commit comments