Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #2109: Recursively unwrap loaders to support template partials #2117

Merged
merged 6 commits into from
Apr 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 9 additions & 6 deletions debug_toolbar/panels/templates/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,18 @@ def template_source(request):
template_name = request.GET.get("template", template_origin_name)

final_loaders = []
loaders = Engine.get_default().template_loaders
loaders = list(Engine.get_default().template_loaders)

while loaders:
loader = loaders.pop(0)

for loader in loaders:
if loader is not None:
# When the loader has loaders associated with it,
# append those loaders to the list. This occurs with
# django.template.loaders.cached.Loader
# Recursively unwrap loaders until we get to loaders which do not
# themselves wrap other loaders. This adds support for
# django.template.loaders.cached.Loader and the
# django-template-partials loader (possibly among others)
if hasattr(loader, "loaders"):
final_loaders += loader.loaders
loaders.extend(loader.loaders)
else:
final_loaders.append(loader)

Expand Down
3 changes: 3 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Pending
* Added hook to RedirectsPanel for subclass customization.
* Added feature to sanitize sensitive data in the Request Panel.
* Fixed dark mode conflict in code block toolbar CSS
* Added support for using django-template-partials with the template panel's
source view functionality. The same change possibly adds support for other
template loaders.

5.1.0 (2025-03-20)
------------------
Expand Down
18 changes: 18 additions & 0 deletions tests/panels/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,24 @@ def test_lazyobject_eval(self):
self.panel.generate_stats(self.request, response)
self.assertIn("lazy_value", self.panel.content)

@override_settings(
DEBUG=True,
DEBUG_TOOLBAR_PANELS=["debug_toolbar.panels.templates.TemplatesPanel"],
)
def test_template_source(self):
from django.core import signing
from django.template.loader import get_template

template = get_template("basic.html")
url = "/__debug__/template_source/"
data = {
"template": template.template.name,
"template_origin": signing.dumps(template.template.origin.name),
}

response = self.client.get(url, data)
self.assertEqual(response.status_code, 200)


@override_settings(
DEBUG=True, DEBUG_TOOLBAR_PANELS=["debug_toolbar.panels.templates.TemplatesPanel"]
Expand Down
5 changes: 5 additions & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# Quick-start development settings - unsuitable for production

DEBUG = False
SECRET_KEY = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"

INTERNAL_IPS = ["127.0.0.1"]
Expand All @@ -27,6 +28,10 @@
"django.contrib.messages",
"django.contrib.staticfiles",
"debug_toolbar",
# We are not actively using template-partials; we just want more nesting
# in our template loader configuration, see
# https://github.com/django-commons/django-debug-toolbar/issues/2109
"template_partials",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we always be testing with template partials? I think with the django-csp tests, we have specific tests that install the package and test against it. That said, this is likely to be a short-time thing. Both django-csp and template-partials are very likely to be merged to core in the 6.x series.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does feel a bit bad, I agree. Another way to test this would have been to add a mock loader with a loaders attribute containing the cached loader configuration and testing the panel like that. I thought it easier and more understandable to add django-template-partials as a test dependency than doing the more involved mocking.

We will have to revisit this when template-partials is merged (hopefully), either by switching to a different package which also wraps the cached loader or by adding the relevant testing code to our project.

"tests",
]

Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ deps =
selenium>=4.8.0
sqlparse
django-csp
django-template-partials
passenv=
CI
COVERAGE_ARGS
Expand Down