Last active
November 15, 2024 22:04
-
-
Save vstoykov/1390853 to your computer and use it in GitHub Desktop.
Django Middleware to print sql queries in debug console
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Originaly code was taken from http://djangosnippets.org/snippets/290/ | |
But I was made some improvements like: | |
- print URL from what queries was | |
- don't show queries from static URLs (MEDIA_URL and STATIC_URL, also for /favicon.ico). | |
- If DEBUG is False tell to django to not use this middleware | |
- Remove guessing of terminal width (This breaks the rendered SQL) | |
- Port to Python 3 and newer versions of Django | |
""" | |
from django.conf import settings | |
from django.core.exceptions import MiddlewareNotUsed | |
from django.db import connection | |
from django.utils.deprecation import MiddlewareMixin | |
class SQLPrintingMiddleware(MiddlewareMixin): | |
""" | |
Middleware which prints out a list of all SQL queries done | |
for each view that is processed. This is only useful for debugging. | |
""" | |
def __init__(self, *args, **kwargs): | |
if not settings.DEBUG: | |
raise MiddlewareNotUsed | |
super().__init__(*args, **kwargs) | |
def process_response(self, request, response): | |
if (len(connection.queries) == 0 or | |
request.path_info.startswith('/favicon.ico') or | |
request.path_info.startswith(settings.STATIC_URL) or | |
request.path_info.startswith(settings.MEDIA_URL)): | |
return response | |
indentation = 2 | |
print("\n\n%s\033[1;35m[SQL Queries for]\033[1;34m %s\033[0m\n" % (" " * indentation, request.path_info)) | |
total_time = 0.0 | |
for query in connection.queries: | |
nice_sql = query['sql'].replace('"', '').replace(',', ', ') | |
sql = "\033[1;31m[%s]\033[0m %s" % (query['time'], nice_sql) | |
total_time += float(query['time']) | |
print("%s%s\n" % (" " * indentation, sql)) | |
replace_tuple = (" " * indentation, str(total_time)) | |
print("%s\033[1;32m[TOTAL TIME: %s seconds]\033[0m" % replace_tuple) | |
return response |
FYI: For newer version of django, would need to provide __init__
and __call__
methods for
class based middleware.(as per https://docs.djangoproject.com/en/5.0/topics/http/middleware/#writing-your-own-middleware_
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
response = self.process_response(request, response)
return response
def process_response(self, request, response):
... # print SQL logic
@peacefulseeker thanks for reminding me about this. The snippet is updated.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
, where 1 could be chaged tosys.stdout.fileno()
also would be nice to swap args
REPORTMAILTASK.USER_ID = :arg1
parts in displayed query to real values (for example REPORTMAILTASK.USER_ID = 888)Nice gist though