diff --git a/debug_toolbar/panels/sql/utils.py b/debug_toolbar/panels/sql/utils.py index a5645f6da..16b7a3ea4 100644 --- a/debug_toolbar/panels/sql/utils.py +++ b/debug_toolbar/panels/sql/utils.py @@ -4,6 +4,8 @@ from django.utils.html import escape from sqlparse import tokens as T +from debug_toolbar import settings as dt_settings + class BoldKeywordFilter: """sqlparse filter to bold SQL keywords""" @@ -31,7 +33,8 @@ def reformat_sql(sql, with_toggle=False): def parse_sql(sql, aligned_indent=False): stack = sqlparse.engine.FilterStack() - stack.enable_grouping() + if dt_settings.get_config()["PRETTIFY_SQL"]: + stack.enable_grouping() if aligned_indent: stack.stmtprocess.append( sqlparse.filters.AlignedIndentFilter(char=" ", n="
") diff --git a/debug_toolbar/settings.py b/debug_toolbar/settings.py index 7ebedff39..d8e6868a3 100644 --- a/debug_toolbar/settings.py +++ b/debug_toolbar/settings.py @@ -37,6 +37,7 @@ "django.utils.deprecation", "django.utils.functional", ), + "PRETTIFY_SQL": True, "PROFILER_MAX_DEPTH": 10, "SHOW_TEMPLATE_CONTEXT": True, "SKIP_TEMPLATE_PREFIXES": ("django/forms/widgets/", "admin/widgets/"), diff --git a/docs/configuration.rst b/docs/configuration.rst index a1618b44f..92b493000 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -180,6 +180,39 @@ Panel options Useful for eliminating server-related entries which can result in enormous DOM structures and toolbar rendering delays. +* ``PRETTIFY_SQL`` + + Default: ``True`` + + Panel: SQL + + Controls SQL token grouping. + + Token grouping allows pretty print of similar tokens, + like aligned indentation for every selected field. + + When set to ``True``, it might cause render slowdowns + when a view make long SQL textual queries. + + **Without grouping**:: + + SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name" + FROM "auth_user" + WHERE "auth_user"."username" = '''test_username''' + LIMIT 21 + + **With grouping**:: + + SELECT "auth_user"."id", + "auth_user"."password", + "auth_user"."last_login", + "auth_user"."is_superuser", + "auth_user"."username", + "auth_user"."first_name", + "auth_user"."last_name", + FROM "auth_user" + WHERE "auth_user"."username" = '''test_username''' + LIMIT 21 * ``PROFILER_MAX_DEPTH`` diff --git a/tests/panels/test_sql.py b/tests/panels/test_sql.py index 479bbc31c..9ed2b1a6e 100644 --- a/tests/panels/test_sql.py +++ b/tests/panels/test_sql.py @@ -9,6 +9,8 @@ from django.shortcuts import render from django.test.utils import override_settings +from debug_toolbar import settings as dt_settings + from ..base import BaseTestCase try: @@ -357,3 +359,40 @@ def test_regression_infinite_recursion(self): # ensure the stacktrace is populated self.assertTrue(len(query[1]["stacktrace"]) > 0) + + @override_settings( + DEBUG_TOOLBAR_CONFIG={"PRETTIFY_SQL": True}, + ) + def test_prettify_sql(self): + """ + Test case to validate that the PRETTIFY_SQL setting changes the output + of the sql when it's toggled. It does not validate what it does + though. + """ + list(User.objects.filter(username__istartswith="spam")) + + response = self.panel.process_request(self.request) + self.panel.generate_stats(self.request, response) + pretty_sql = self.panel._queries[-1][1]["sql"] + self.assertEqual(len(self.panel._queries), 1) + + # Reset the queries + self.panel._queries = [] + # Run it again, but with prettyify off. Verify that it's different. + dt_settings.get_config()["PRETTIFY_SQL"] = False + list(User.objects.filter(username__istartswith="spam")) + response = self.panel.process_request(self.request) + self.panel.generate_stats(self.request, response) + self.assertEqual(len(self.panel._queries), 1) + self.assertNotEqual(pretty_sql, self.panel._queries[-1][1]["sql"]) + + self.panel._queries = [] + # Run it again, but with prettyify back on. + # This is so we don't have to check what PRETTIFY_SQL does exactly, + # but we know it's doing something. + dt_settings.get_config()["PRETTIFY_SQL"] = True + list(User.objects.filter(username__istartswith="spam")) + response = self.panel.process_request(self.request) + self.panel.generate_stats(self.request, response) + self.assertEqual(len(self.panel._queries), 1) + self.assertEqual(pretty_sql, self.panel._queries[-1][1]["sql"])