Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bb88c05
Add the Store API and initial documentation.
tim-schilling May 17, 2023
19b5695
Remove config from docs as sphinx says it's misspelled.
tim-schilling May 17, 2023
97fcda7
Switch to Store.request_ids and remove serialization force_str.
tim-schilling Jun 17, 2023
487dfb3
Log serialization warning when a panel errors. (#1810)
tim-schilling Aug 21, 2023
e7cf575
Ignore common venv folder.
tim-schilling Aug 20, 2023
c4201fa
Rename store_id variants to request_id
Aug 20, 2023
bbbbb34
Support serializable panels. This is a WIP and needs clean-up.
Aug 20, 2023
e2f695b
Support serializable sql panel
tim-schilling Aug 21, 2023
14a5e0c
Make Panel.panel_id a classmember.
tim-schilling Aug 21, 2023
a31115f
Force everything to a string if it can't be serialized.
tim-schilling Aug 29, 2023
71edcf5
Support serialization of FunctionCall
tim-schilling Aug 29, 2023
c03f08f
Update all panels to use data from get_stats on render
tim-schilling Sep 5, 2023
47bdabe
Extend example app to have an async version.
tim-schilling Sep 5, 2023
dd53424
Merge branch 'main' into serialize-panels
tim-schilling Jul 10, 2024
16e02f5
Rework the alerts panel to be compatible with serialization.
tim-schilling Jul 10, 2024
3e4c484
Make template panel serializable.
tim-schilling Jul 10, 2024
f4ff5f4
Avoid caching the config settings.
Jul 11, 2024
d3730a6
Fix tests for serializable changes with selenium.
Jul 11, 2024
c660269
Comment out the async button because it breaks the wsgi app.
Jul 11, 2024
8402c4d
Hack: Sleep before checking to see if the history panel auto updated.
Jul 11, 2024
e1c0755
Improve clarity of record_stats for serialization. (#1965)
tim-schilling Jul 19, 2024
5a21920
Merge branch 'main' into serializable
tim-schilling Feb 9, 2025
89c4786
Added check for pytest as test runner for IS_RUNNING_TESTS.
tim-schilling May 14, 2025
73eea66
Fixes #2073 -- Added DatabaseStore for persistent debug data storage.…
dr-rompecabezas May 14, 2025
153c22b
Merge branch 'main' into serializable
tim-schilling May 15, 2025
f8bfb0d
Move serializable changes into the main change log.
tim-schilling May 15, 2025
bf77c70
Updated replaceToolbarState to use request id.
tim-schilling May 15, 2025
0cbf478
Merge branch 'main' into serializable
matthiask May 23, 2025
7a638c7
Removed unnecessary SQLPanel.record_stats
tim-schilling Jun 3, 2025
2fafbb4
Merge branch 'main' into serializable
tim-schilling Jul 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge branch 'main' into serialize-panels
  • Loading branch information
tim-schilling committed Jul 10, 2024
commit dd534240d79cf8764cb43d4ad1c76c596c1565bb
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ htmlcov
geckodriver.log
coverage.xml
venv
.direnv/
.envrc
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ example_async:
--noinput --username="$(USER)" --email="$(USER)@mailinator.com"
daphne example.asgi:application

example_test:
python example/manage.py test example

test:
DJANGO_SETTINGS_MODULE=tests.settings \
Expand Down
17 changes: 9 additions & 8 deletions debug_toolbar/panels/templates/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def title(self):
def nav_subtitle(self):
templates = self.get_stats()["templates"]
if templates:
return templates[0]["name"]
return self.templates[0]["template"].name
return ""

template = "debug_toolbar/panels/templates.html"
Expand Down Expand Up @@ -187,6 +187,7 @@ def process_context_list(self, context_layers):
def generate_stats(self, request, response):
template_context = []
for template_data in self.templates:
info = {}
# Clean up some info about templates
template = template_data["template"]
if hasattr(template, "origin") and template.origin and template.origin.name:
Expand All @@ -195,15 +196,15 @@ def generate_stats(self, request, response):
else:
template.origin_name = _("No origin")
template.origin_hash = ""
context = {
"template": force_str(template),
"name": template.name,
}
info["template"] = template
# Clean up context for better readability
if self.toolbar.config["SHOW_TEMPLATE_CONTEXT"]:
context_list = template_data.get("context", [])
context["context"] = "\n".join(context_list)
template_context.append(context)
if "context_list" not in template_data:
template_data["context_list"] = self.process_context_list(
template_data.get("context", [])
)
info["context"] = "\n".join(template_data["context_list"])
template_context.append(info)

# Fetch context_processors/template_dirs from any template
if self.templates:
Expand Down
3 changes: 3 additions & 0 deletions debug_toolbar/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
"OBSERVE_REQUEST_CALLBACK": "debug_toolbar.toolbar.observe_request",
"TOOLBAR_LANGUAGE": None,
"TOOLBAR_STORE_CLASS": "debug_toolbar.store.MemoryStore",
"IS_RUNNING_TESTS": "test" in sys.argv,
"UPDATE_ON_FETCH": False,
"DEFAULT_THEME": "auto",
}


Expand Down
4 changes: 3 additions & 1 deletion debug_toolbar/static/debug_toolbar/js/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,9 @@ const djdt = {
requestId = encodeURIComponent(requestId);
const dest = `${sidebarUrl}?request_id=${requestId}`;
slowjax(dest).then(function (data) {
replaceToolbarState(requestId, data);
if (djdt.needUpdateOnFetch) {
replaceToolbarState(requestId, data);
}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
</td>
<td class="djdt-actions">
<form method="get" action="{% url 'djdt:history_sidebar' %}">
{{ history_context.form }}
{{ history_context.form.as_div }}
<button data-request-id="{{ request_id }}" class="switchHistory">Switch</button>
</form>
</td>
Expand Down
28 changes: 27 additions & 1 deletion debug_toolbar/toolbar.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"""
The main DebugToolbar class that loads and renders the Toolbar.
"""

import logging
import re
import uuid
from functools import lru_cache

Expand Down Expand Up @@ -177,7 +179,7 @@ def observe_request(request):
"""
Determine whether to update the toolbar from a client side request.
"""
return not DebugToolbar.is_toolbar_request(request)
return True


def from_store_get_response(request):
Expand Down Expand Up @@ -213,3 +215,27 @@ def from_store(cls, request_id, panel_id=None):
panel.load_stats_from_store(data)
toolbar._panels[panel.panel_id] = panel
return toolbar


def debug_toolbar_urls(prefix="__debug__"):
"""
Return a URL pattern for serving toolbar in debug mode.

from django.conf import settings
from debug_toolbar.toolbar import debug_toolbar_urls

urlpatterns = [
# ... the rest of your URLconf goes here ...
] + debug_toolbar_urls()
"""
if not prefix:
raise ImproperlyConfigured("Empty urls prefix not permitted")
elif not settings.DEBUG:
# No-op if not in debug mode.
return []
return [
re_path(
r"^%s/" % re.escape(prefix.lstrip("/")),
include("debug_toolbar.urls"),
),
]
30 changes: 0 additions & 30 deletions tests/panels/test_staticfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,33 +47,3 @@ def test_insert_content(self):
"django.contrib.staticfiles.finders.AppDirectoriesFinder", content
)
self.assertValidHTML(content)

@unittest.skipIf(django.VERSION >= (4,), "Django>=4 handles missing dirs itself.")
@override_settings(
STATICFILES_DIRS=[PATH_DOES_NOT_EXIST] + settings.STATICFILES_DIRS,
STATIC_ROOT=PATH_DOES_NOT_EXIST,
)
def test_finder_directory_does_not_exist(self):
"""Misconfigure the static files settings and verify the toolbar runs.

The test case is that the STATIC_ROOT is in STATICFILES_DIRS and that
the directory of STATIC_ROOT does not exist.
"""
response = self.panel.process_request(self.request)
self.panel.generate_stats(self.request, response)
content = self.panel.content
self.assertIn(
"django.contrib.staticfiles.finders.AppDirectoriesFinder", content
)
self.assertNotIn(
"django.contrib.staticfiles.finders.FileSystemFinder (2 files)", content
)
self.assertEqual(self.panel.get_stats()["num_used"], 0)
self.assertNotEqual(self.panel.get_stats()["num_found"], 0)
expected_apps = ["django.contrib.admin", "debug_toolbar"]
if settings.USE_GIS:
expected_apps = ["django.contrib.gis"] + expected_apps
self.assertEqual(self.panel.get_staticfiles_apps(), expected_apps)
self.assertEqual(
self.panel.get_staticfiles_dirs(), finders.FileSystemFinder().locations
)
2 changes: 2 additions & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,6 @@
# Django's test client sets wsgi.multiprocess to True inappropriately
"RENDER_PANELS": False,
"RESULTS_CACHE_SIZE": 3,
# IS_RUNNING_TESTS must be False even though we're running tests because we're running the toolbar's own tests.
"IS_RUNNING_TESTS": False,
}
5 changes: 3 additions & 2 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,9 +645,10 @@ def test_basic_jinja(self):
# Click to show the template panel
self.selenium.find_element(By.CLASS_NAME, TemplatesPanel.panel_id).click()

self.assertIn("Templates (2 rendered)", template_panel.text)
# This should be 2 templates rendered, including base.html See
# JinjaTemplateTestCase.test_django_jinja2_parent_template_instrumented
self.assertIn("Templates (1 rendered)", template_panel.text)
self.assertIn("base.html", template_panel.text)
self.assertIn("jinja2/basic.jinja", template_panel.text)

@override_settings(
DEBUG_TOOLBAR_CONFIG={
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.