Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
48ac250
Add .prof File Download Support to Profiling Panel
andoriyaprashant Jun 18, 2025
49f29eb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 18, 2025
7ec7f25
Merge branch 'main' of https://github.com/django-commons/django-debug…
JohananOppongAmoateng Dec 17, 2025
fe4e305
Refactor profiling panel and add download functionality for .prof files
JohananOppongAmoateng Dec 17, 2025
5db558d
Add profiling data download functionality and related settings
JohananOppongAmoateng Dec 17, 2025
74ddf5e
Add tests for profiling stats generation and download functionality
JohananOppongAmoateng Dec 17, 2025
5bbb211
fix
JohananOppongAmoateng Dec 17, 2025
a285d82
fix
JohananOppongAmoateng Dec 17, 2025
2bd5cfe
fix
JohananOppongAmoateng Dec 17, 2025
e698cde
Merge branch 'main' into download-prof-files
JohananOppongAmoateng Dec 17, 2025
66e2d50
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 17, 2025
3896fe3
Merge branch 'main' of https://github.com/django-commons/django-debug…
JohananOppongAmoateng Feb 7, 2026
09f2ba0
address problems
JohananOppongAmoateng Feb 7, 2026
9829c58
docs
JohananOppongAmoateng Feb 7, 2026
cfc244b
address review concerns
JohananOppongAmoateng Feb 8, 2026
df258a2
Merge branch 'main' into download-prof-files
tim-schilling May 7, 2026
efbd2b9
Clean up PR.
tim-schilling May 7, 2026
9cbdf04
Generate the prof file on the fly.
tim-schilling May 7, 2026
05a505c
Merge branch 'main' into download-prof-files
tim-schilling May 9, 2026
34dde67
Name the profile file based on the request being made.
tim-schilling May 9, 2026
bdb6bf5
Remove the mocks from the profiling panel's integration tests.
tim-schilling May 9, 2026
776e4ba
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 9, 2026
25fa939
Remove unexpected addition of uv.lock.
tim-schilling May 9, 2026
f1c86c2
Switch to a proper FileResponse response.
tim-schilling May 10, 2026
d03fec3
Remove extra change.
tim-schilling May 10, 2026
7235ab8
Convert to a NamedTuple class.
tim-schilling May 10, 2026
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
Switch to a proper FileResponse response.
  • Loading branch information
tim-schilling committed May 10, 2026
commit f1c86c2729192c3994a264d3980739a917032de1
12 changes: 7 additions & 5 deletions debug_toolbar/panels/profiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django import forms
from django.conf import settings
from django.contrib.auth.decorators import login_not_required
from django.http import Http404, HttpResponse, HttpResponseBadRequest
from django.http import FileResponse, Http404, HttpResponseBadRequest
from django.urls import path
from django.utils import timezone
from django.utils.html import format_html
Expand Down Expand Up @@ -312,8 +312,10 @@ def profiling_download(request):
if "func_list" not in panel_stats:
return HttpResponseBadRequest("No profiling data exists for this request.")
content = _print_stats_from_function_calls(panel_stats["func_list"])
response = HttpResponse(content, content_type="text/plain")
profile_name = panel_stats.get("profile_name") or f"request-{request_id}"
response["Content-Disposition"] = f'attachment; filename="{profile_name}.prof"'
return response
return FileResponse(
content,
as_attachment=True,
filename=f"{panel_stats['profile_name']}.prof",
content_type="text/plain",
)
return HttpResponseBadRequest(f"Form errors: {form.errors}")
9 changes: 6 additions & 3 deletions tests/panels/test_profiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,13 @@ def test_profiling_download(self):
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response["Content-Type"], "text/plain")
self.assertIn(".prof", response["Content-Disposition"])
content = response.content.decode()
self.assertRegex(
response.filename,
r"<unavailable>-.*\.prof",
)
content = b"".join(response.streaming_content)
self.assertIn(
" ncalls tottime percall cumtime percall filename:lineno(function)",
b" ncalls tottime percall cumtime percall filename:lineno(function)",
content,
)

Expand Down