Skip to content

Commit c63ee81

Browse files
committed
refactor: add contextvar to enable/disable tracking of DDT models
1 parent 0c81176 commit c63ee81

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

debug_toolbar/panels/sql/tracking.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from django.utils.encoding import force_str
99

1010
from debug_toolbar.utils import get_stack_trace, get_template_info
11+
from django.apps import apps
1112

1213
try:
1314
import psycopg
@@ -27,6 +28,17 @@
2728
# additional queries.
2829
allow_sql = contextvars.ContextVar("debug-toolbar-allow-sql", default=True)
2930

31+
# Prevents tracking of DDT models
32+
allow_ddt_models_tracking = contextvars.ContextVar(
33+
"debug-toolbar-allow-ddt-models", default=False
34+
)
35+
36+
DDT_MODELS = {
37+
m._meta.db_table
38+
for m in apps.get_app_config("debug_toolbar").get_models()
39+
if m._meta.app_label == "debug_toolbar"
40+
}
41+
3042

3143
class SQLQueryTriggered(Exception):
3244
"""Thrown when template panel triggers a query"""
@@ -224,6 +236,12 @@ def _record(self, method, sql, params):
224236
}
225237
)
226238

239+
# Skip recording if query includes DDT models.
240+
if not allow_ddt_models_tracking.get() and any(
241+
table in sql for table in DDT_MODELS
242+
):
243+
return
244+
227245
# We keep `sql` to maintain backwards compatibility
228246
self.logger.record(**kwargs)
229247

tests/panels/test_sql.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import debug_toolbar.panels.sql.tracking as sql_tracking
1818
from debug_toolbar.panels.sql import SQLPanel
19+
from debug_toolbar.models import HistoryEntry
1920

2021
try:
2122
import psycopg
@@ -33,6 +34,20 @@ def sql_call(*, use_iterator=False):
3334
return list(qs)
3435

3536

37+
def sql_call_ddt(*, use_iterator=False):
38+
qs = HistoryEntry.objects.all()
39+
if use_iterator:
40+
qs = qs.iterator()
41+
return list(qs)
42+
43+
44+
async def async_sql_call_ddt(*, use_iterator=False):
45+
qs = HistoryEntry.objects.all()
46+
if use_iterator:
47+
qs = qs.iterator()
48+
return await sync_to_async(list)(qs)
49+
50+
3651
async def async_sql_call(*, use_iterator=False):
3752
qs = User.objects.all()
3853
if use_iterator:
@@ -104,6 +119,64 @@ async def test_recording_concurrent_async(self):
104119
# ensure the stacktrace is populated
105120
self.assertTrue(len(query["stacktrace"]) > 0)
106121

122+
def test_ddt_models_tracking(self):
123+
self.assertEqual(len(self.panel._queries), 0)
124+
125+
# enable ddt tracking
126+
sql_tracking.allow_ddt_models_tracking.set(True)
127+
128+
sql_call_ddt()
129+
130+
# ensure query was logged
131+
self.assertEqual(len(self.panel._queries), 1)
132+
query = self.panel._queries[0]
133+
self.assertEqual(query["alias"], "default")
134+
self.assertTrue("sql" in query)
135+
self.assertTrue("duration" in query)
136+
self.assertTrue("stacktrace" in query)
137+
138+
# ensure the stacktrace is populated
139+
self.assertTrue(len(self.panel._queries), 0)
140+
141+
async def test_ddt_models_tracking_async(self):
142+
self.assertEqual(len(self.panel._queries), 0)
143+
144+
# enable ddt tracking
145+
sql_tracking.allow_ddt_models_tracking.set(True)
146+
147+
await async_sql_call_ddt()
148+
149+
# ensure query was logged
150+
self.assertEqual(len(self.panel._queries), 1)
151+
query = self.panel._queries[0]
152+
self.assertEqual(query["alias"], "default")
153+
self.assertTrue("sql" in query)
154+
self.assertTrue("duration" in query)
155+
self.assertTrue("stacktrace" in query)
156+
157+
# ensure the stacktrace is populated
158+
self.assertTrue(len(self.panel._queries), 0)
159+
160+
def test_ddt_models_untracking(self):
161+
self.assertEqual(len(self.panel._queries), 0)
162+
163+
# disable ddt tracking
164+
sql_tracking.allow_ddt_models_tracking.set(False)
165+
166+
sql_call_ddt()
167+
168+
self.assertEqual(len(self.panel._queries), 0)
169+
170+
async def test_ddt_models_untracking_async(self):
171+
self.assertEqual(len(self.panel._queries), 0)
172+
173+
# enable ddt tracking
174+
sql_tracking.allow_ddt_models_tracking.set(False)
175+
176+
await async_sql_call_ddt()
177+
178+
self.assertEqual(len(self.panel._queries), 0)
179+
107180
@unittest.skipUnless(
108181
connection.vendor == "postgresql", "Test valid only on PostgreSQL"
109182
)

0 commit comments

Comments
 (0)