From 1756c3f2b236c736d75c3db9d25fa184cb135fbf Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Sat, 21 Feb 2026 22:45:04 +0300 Subject: [PATCH] feat(debug): integrate `django-debug-toolbar` for enhanced debugging Add `django-debug-toolbar` to assist with in-depth debugging during development. Updates were made to `settings`, `urls`, and dependency files to enable this feature. --- pyproject.toml | 2 ++ schon/settings/base.py | 17 +++++++++++++ schon/urls.py | 3 +++ uv.lock | 57 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 9d14ed1a..6fdf69eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ dependencies = [ "django-ratelimit==4.1.0", "django-storages==1.14.6", "django-unfold==0.80.2", + "django-debug-toolbar==6.2.0", "django-widget-tweaks==1.5.1", "djangorestframework==3.16.1", "djangorestframework-recursive==0.1.2", @@ -51,6 +52,7 @@ dependencies = [ "graphene-django==3.2.3", "graphene-file-upload==1.3.0", "httpx==0.28.1", + "opentelemetry-instrumentation-django==0.60b1", "paramiko==4.0.0", "pillow==12.1.1", "pip==26.0.1", diff --git a/schon/settings/base.py b/schon/settings/base.py index eda7898f..eb9e1901 100644 --- a/schon/settings/base.py +++ b/schon/settings/base.py @@ -159,6 +159,7 @@ INSTALLED_APPS: list[str] = [ if DEBUG: wn_app_index = INSTALLED_APPS.index("django.contrib.staticfiles") - 1 INSTALLED_APPS.insert(wn_app_index, "whitenoise.runserver_nostatic") + INSTALLED_APPS.append("debug_toolbar") MIDDLEWARE: list[str] = [ "schon.middleware.BlockInvalidHostMiddleware", @@ -179,6 +180,12 @@ MIDDLEWARE: list[str] = [ "django_prometheus.middleware.PrometheusAfterMiddleware", ] +if DEBUG: + MIDDLEWARE.insert( + MIDDLEWARE.index("django.contrib.sessions.middleware.SessionMiddleware"), + "debug_toolbar.middleware.DebugToolbarMiddleware", + ) + TEMPLATES: list[ dict[str, str | list[str | Path] | dict[str, str | list[str]] | Path | bool] ] = [ @@ -393,6 +400,16 @@ INTERNAL_IPS: list[str] = [ "127.0.0.1", ] +if DEBUG: + import socket + + # Docker: resolve container's gateway IP so debug toolbar works + try: + _, _, ips = socket.gethostbyname_ex(socket.gethostname()) + INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips] + except socket.gaierror: + pass + if getenv("SENTRY_DSN"): import sentry_sdk from sentry_sdk.integrations.celery import CeleryIntegration diff --git a/schon/urls.py b/schon/urls.py index d86d4f4f..f53214f0 100644 --- a/schon/urls.py +++ b/schon/urls.py @@ -115,4 +115,7 @@ urlpatterns = [ ] if settings.DEBUG: + from debug_toolbar.toolbar import debug_toolbar_urls + + urlpatterns += debug_toolbar_urls() urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/uv.lock b/uv.lock index fa40991d..c56c6247 100644 --- a/uv.lock +++ b/uv.lock @@ -828,6 +828,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1a/6f/ff400d50fd71226e9d16a210c5d097bb797ec21879019ba260365d42e490/django_dbbackup-5.2.0-py3-none-any.whl", hash = "sha256:540948869e44778b5b33333cbab0cfe44279defd47df635d309ede8666894370", size = 35981, upload-time = "2026-02-11T04:47:38.081Z" }, ] +[[package]] +name = "django-debug-toolbar" +version = "6.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, + { name = "sqlparse" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f1/4d/6acf660500d3d581bfc19460d9605cdf14c275640f35825da1329eaafafa/django_debug_toolbar-6.2.0.tar.gz", hash = "sha256:dc1c174d8fb0ea01435e02d9ceef735cf62daf37c1a6a5692d33b4127327679b", size = 313779, upload-time = "2026-01-20T12:38:25.268Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/04/e24611299a5ee0d4edfacf935b09cfb7d5d9cb653bd7b7883c3b43a6f90d/django_debug_toolbar-6.2.0-py3-none-any.whl", hash = "sha256:1575461954e6befa720e999dec13fe4f1cc8baf40b6c3ac2aec5f340c0f9c85f", size = 271354, upload-time = "2026-01-20T12:38:23.608Z" }, +] + [[package]] name = "django-elasticsearch-dsl" version = "8.2" @@ -2429,6 +2442,37 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/77/d2/6788e83c5c86a2690101681aeef27eeb2a6bf22df52d3f263a22cee20915/opentelemetry_instrumentation-0.60b1-py3-none-any.whl", hash = "sha256:04480db952b48fb1ed0073f822f0ee26012b7be7c3eac1a3793122737c78632d", size = 33096, upload-time = "2025-12-11T13:35:33.067Z" }, ] +[[package]] +name = "opentelemetry-instrumentation-django" +version = "0.60b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-instrumentation-wsgi" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-util-http" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/dc/a42fb5ff5c4ea8128d7c61a322e0cfbeae0fd204fc63a679f73caeec266e/opentelemetry_instrumentation_django-0.60b1.tar.gz", hash = "sha256:765b69c7ccdea7e9ebfd0b9e68387956b8f74816f3e39775d5b06a20f16b0522", size = 26599, upload-time = "2025-12-11T13:36:56.293Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/05/6b348ea989f7a9e1e6311fa653e113bd39f4506771323e27a639c2a1ea54/opentelemetry_instrumentation_django-0.60b1-py3-none-any.whl", hash = "sha256:3f6b4ba201eee35406dab965b254eed0c64fa1ef42e4a7b0296ad1b30e8e3f81", size = 21172, upload-time = "2025-12-11T13:35:57.365Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-wsgi" +version = "0.60b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-util-http" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/24/5632d31506a27650567fdff8f9be37fc4d98396b6331617be69bd332bf77/opentelemetry_instrumentation_wsgi-0.60b1.tar.gz", hash = "sha256:eb553eec7ebfcf2945cc10d787a265e7abadb9ed1d1ebce8b13988d44fa0cf45", size = 19167, upload-time = "2025-12-11T13:37:20.3Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/98/c637d9e5cab1355d6765de2304199a1d79a43aa94c33d8eddb475327d81a/opentelemetry_instrumentation_wsgi-0.60b1-py3-none-any.whl", hash = "sha256:5e7b432778ebf5a39af136227884a6ab2efc3c4e73e2dbb1d05ecf03ea196705", size = 14583, upload-time = "2025-12-11T13:36:33.164Z" }, +] + [[package]] name = "opentelemetry-sdk" version = "1.39.1" @@ -2456,6 +2500,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7a/5e/5958555e09635d09b75de3c4f8b9cae7335ca545d77392ffe7331534c402/opentelemetry_semantic_conventions-0.60b1-py3-none-any.whl", hash = "sha256:9fa8c8b0c110da289809292b0591220d3a7b53c1526a23021e977d68597893fb", size = 219982, upload-time = "2025-12-11T13:32:36.955Z" }, ] +[[package]] +name = "opentelemetry-util-http" +version = "0.60b1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/50/fc/c47bb04a1d8a941a4061307e1eddfa331ed4d0ab13d8a9781e6db256940a/opentelemetry_util_http-0.60b1.tar.gz", hash = "sha256:0d97152ca8c8a41ced7172d29d3622a219317f74ae6bb3027cfbdcf22c3cc0d6", size = 11053, upload-time = "2025-12-11T13:37:25.115Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/5c/d3f1733665f7cd582ef0842fb1d2ed0bc1fba10875160593342d22bba375/opentelemetry_util_http-0.60b1-py3-none-any.whl", hash = "sha256:66381ba28550c91bee14dcba8979ace443444af1ed609226634596b4b0faf199", size = 8947, upload-time = "2025-12-11T13:36:37.151Z" }, +] + [[package]] name = "orjson" version = "3.11.7" @@ -3296,6 +3349,7 @@ dependencies = [ { name = "django-constance" }, { name = "django-cors-headers" }, { name = "django-dbbackup" }, + { name = "django-debug-toolbar" }, { name = "django-elasticsearch-dsl" }, { name = "django-extensions" }, { name = "django-filter" }, @@ -3328,6 +3382,7 @@ dependencies = [ { name = "graphene-django" }, { name = "graphene-file-upload" }, { name = "httpx" }, + { name = "opentelemetry-instrumentation-django" }, { name = "paramiko" }, { name = "pillow" }, { name = "pip" }, @@ -3395,6 +3450,7 @@ requires-dist = [ { name = "django-constance", specifier = "==4.3.4" }, { name = "django-cors-headers", specifier = "==4.9.0" }, { name = "django-dbbackup", specifier = "==5.2.0" }, + { name = "django-debug-toolbar", specifier = "==6.2.0" }, { name = "django-elasticsearch-dsl", specifier = "==8.2" }, { name = "django-extensions", specifier = "==4.1" }, { name = "django-filter", specifier = "==25.2" }, @@ -3431,6 +3487,7 @@ requires-dist = [ { name = "httpx", specifier = "==0.28.1" }, { name = "jupyter", marker = "extra == 'jupyter'", specifier = "==1.1.1" }, { name = "openai", marker = "extra == 'openai'", specifier = "==2.21.0" }, + { name = "opentelemetry-instrumentation-django", specifier = "==0.60b1" }, { name = "paramiko", specifier = "==4.0.0" }, { name = "pillow", specifier = "==12.1.1" }, { name = "pip", specifier = "==26.0.1" },