Skip to content

Commit 2afa619

Browse files
committed
Adding heuristic function for observing requests
Also adding generate_headers function
1 parent 1e58d66 commit 2afa619

File tree

6 files changed

+47
-28
lines changed

6 files changed

+47
-28
lines changed

debug_toolbar/middleware.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ def show_toolbar(request):
2121
return settings.DEBUG and request.META.get("REMOTE_ADDR") in settings.INTERNAL_IPS
2222

2323

24+
def observe_request(request):
25+
"""
26+
Default function to determine whether to update the toolbar from a client side request
27+
"""
28+
return not DebugToolbar.is_toolbar_request(request)
29+
30+
2431
@lru_cache()
2532
def get_show_toolbar():
2633
# If SHOW_TOOLBAR_CALLBACK is a string, which is the recommended
@@ -32,6 +39,17 @@ def get_show_toolbar():
3239
return func_or_path
3340

3441

42+
@lru_cache()
43+
def get_observe_request():
44+
# If OBSERVE_REQUEST_CALLBACK is a string, which is the recommended
45+
# setup, resolve it to the corresponding callable.
46+
func_or_path = dt_settings.get_config()["OBSERVE_REQUEST_CALLBACK"]
47+
if isinstance(func_or_path, str):
48+
return import_string(func_or_path)
49+
else:
50+
return func_or_path
51+
52+
3553
class DebugToolbarMiddleware:
3654
"""
3755
Middleware to set up Debug Toolbar on incoming request and render toolbar
@@ -67,12 +85,12 @@ def __call__(self, request):
6785
panel.generate_stats(request, response)
6886
panel.generate_server_timing(request, response)
6987

70-
response = self.generate_server_timing_header(response, toolbar.enabled_panels)
71-
7288
# Always render the toolbar for the history panel, even if it is not
7389
# included in the response.
7490
rendered = toolbar.render_toolbar()
7591

92+
response = self.generate_headers(request, response, toolbar.enabled_panels)
93+
7694
# Check for responses where the toolbar can't be inserted.
7795
content_encoding = response.get("Content-Encoding", "")
7896
content_type = response.get("Content-Type", "").split(";")[0]
@@ -96,22 +114,24 @@ def __call__(self, request):
96114
return response
97115

98116
@staticmethod
99-
def generate_server_timing_header(response, panels):
100-
data = []
117+
def generate_headers(request, response, panels):
118+
stats_data = []
101119

102120
for panel in panels:
121+
response = panel.generate_headers(request, response)
103122
stats = panel.get_server_timing_stats()
104123
if not stats:
105124
continue
106125

107126
for key, record in stats.items():
108127
# example: `SQLPanel_sql_time;dur=0;desc="SQL 0 queries"`
109-
data.append(
128+
stats_data.append(
110129
'{}_{};dur={};desc="{}"'.format(
111130
panel.panel_id, key, record.get("value"), record.get("title")
112131
)
113132
)
114133

115-
if data:
116-
response["Server-Timing"] = ", ".join(data)
134+
if stats_data:
135+
response["Server-Timing"] = ", ".join(stats_data)
136+
117137
return response

debug_toolbar/panels/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,15 @@ def process_request(self, request):
192192
"""
193193
return self.get_response(request)
194194

195+
def generate_headers(self, request, response):
196+
"""
197+
Attach headers to response.
198+
199+
Call after procssing the request, gives the panel an opportunity to
200+
add headers to the outgoing response
201+
"""
202+
return response
203+
195204
def generate_stats(self, request, response):
196205
"""
197206
Called after :meth:`process_request

debug_toolbar/panels/history/panel.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from django.utils import timezone
99
from django.utils.translation import gettext_lazy as _
1010

11+
from debug_toolbar.middleware import get_observe_request
1112
from debug_toolbar.panels import Panel
1213
from debug_toolbar.panels.history import views
1314
from debug_toolbar.panels.history.forms import HistoryStoreForm
@@ -20,11 +21,10 @@ class HistoryPanel(Panel):
2021
nav_title = _("History")
2122
template = "debug_toolbar/panels/history.html"
2223

23-
def process_request(self, request):
24-
response = super().process_request(request)
25-
if not self.toolbar.should_render_panels():
26-
self.toolbar.store()
27-
store_id = self.toolbar.store_id
24+
def generate_headers(self, request, response):
25+
observe_request = get_observe_request()
26+
store_id = getattr(self.toolbar, "store_id")
27+
if store_id and observe_request(request):
2828
sig = SignedDataForm(
2929
initial=HistoryStoreForm(initial={"store_id": store_id}).initial
3030
).initial.get("signed")

debug_toolbar/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"SHOW_TEMPLATE_CONTEXT": True,
3838
"SKIP_TEMPLATE_PREFIXES": ("django/forms/widgets/", "admin/widgets/"),
3939
"SQL_WARNING_THRESHOLD": 500, # milliseconds
40-
"UPDATE_ON_AJAX": False,
40+
"OBSERVE_REQUEST_CALLBACK": "debug_toolbar.middleware.observe_request",
4141
}
4242

4343

debug_toolbar/templates/debug_toolbar/base.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
data-store-id="{{ toolbar.store_id }}"
1212
data-render-panel-url="{% url 'djdt:render_panel' %}"
1313
{% endif %}
14-
{% if toolbar.should_update_on_ajax %}
15-
data-sidebar-url="{% url 'djdt:history_sidebar' %}"
14+
{% url 'djdt:history_sidebar' as history_url %}
15+
{% if history_url %}
16+
data-sidebar-url="{{ history_url }}"
1617
{% endif %}
1718
data-default-show="{% if toolbar.config.SHOW_COLLAPSED %}false{% else %}true{% endif %}"
1819
{{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }}>

debug_toolbar/toolbar.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
from django.core.exceptions import ImproperlyConfigured
1010
from django.template import TemplateSyntaxError
1111
from django.template.loader import render_to_string
12-
from django.urls import path, resolve, reverse
13-
from django.urls.exceptions import NoReverseMatch, Resolver404
12+
from django.urls import path, resolve
13+
from django.urls.exceptions import Resolver404
1414
from django.utils.module_loading import import_string
1515

1616
from debug_toolbar import settings as dt_settings
@@ -88,17 +88,6 @@ def should_render_panels(self):
8888
render_panels = self.request.META["wsgi.multiprocess"]
8989
return render_panels
9090

91-
def should_update_on_ajax(self):
92-
"""Determine whether the toolbar should consider ajax requests as updates or not"""
93-
has_endpoint_registered = False
94-
try:
95-
reverse("djdt:history_sidebar")
96-
has_endpoint_registered = True
97-
except NoReverseMatch:
98-
pass
99-
should_watch = self.config["UPDATE_ON_AJAX"]
100-
return should_watch and has_endpoint_registered
101-
10291
# Handle storing toolbars in memory and fetching them later on
10392

10493
_store = OrderedDict()

0 commit comments

Comments
 (0)