""" $Id: SQLLogMiddleware.py 306 2007-10-22 14:55:47Z tguettler $ This middleware in settings.py you need to set DEBUG=True DEBUG_SQL=True # Since you can't see the output if the page results in a redirect, # you can log the result into a directory: # DEBUG_SQL='/mypath/...' MIDDLEWARE_CLASSES = ( 'YOURPATH.SQLLogMiddleware.SQLLogMiddleware', 'django.middleware.transaction.TransactionMiddleware', ...) Slightly modified from original by Rob van der Linde - Now supports XHTML content types - Now generates a nice dropdown window/banner at the top of the page. Only works in Firefox (and other standards compliant browsers), but then, no serious developers use IE anyway... """ import re, os, time, datetime from django.conf import settings from django.db import connection from django.template import Template, Context _HEAD_SECTION_RE = re.compile(r'()', re.DOTALL) _BODY_SECTION_RE = re.compile(r'()', re.DOTALL) class SQLLogMiddleware: start = None def process_request(self, request): self.start = time.time() def process_response (self, request, response): # self.start is empty if an append slash redirect happened. debug_sql = getattr(settings, "DEBUG_SQL", False) if (not self.start) or not (settings.DEBUG and debug_sql): return response timesql = 0.0 for q in connection.queries: timesql += float(q['time']) seen = {} duplicate = 0 for q in connection.queries: sql = q["sql"] c = seen.get(sql, 0) if c: duplicate += 1 q["seen"] = c seen[sql] = c + 1 t = Template('''
Django SQL log for this page: click to toggle

request.path: {{ request.path|escape }}
Total query count: {{ queries|length }}
Total duplicate query count: {{ duplicate }}
Total SQL execution time: {{ timesql }}
Total Request execution time: {{ timerequest }}

{% if queries %} {% for sql in queries %} {% endfor %}
Time Frequency SQL
{{ sql.time }} {{ sql.seen }} {{ sql.sql }}
{% else %}

No SQL queries for ths page.

{% endif %} {% if duplicate %}

To avoid duplicates, read: Caching and Querysets.

{% endif %}
''') c = Template(r''' ''') timerequest = round(time.time() - self.start, 3) queries = connection.queries html = str(t.render(Context(locals()))) css = str(c.render(Context(locals()))) if debug_sql == True: if response.get("content-type", "").startswith("text/html") or response.get("content-type", "").startswith("application/xhtml+xml"): tag = _BODY_SECTION_RE.search(response.content) if tag: response.content = _BODY_SECTION_RE.sub(tag.group(0) + html, response.content) tag = _HEAD_SECTION_RE.search(response.content) if tag: response.content = _HEAD_SECTION_RE.sub(css + tag.group(0), response.content) return response assert os.path.isdir(debug_sql), debug_sql outfile = os.path.join(debug_sql, "%s.html" % datetime.datetime.now().isoformat()) fd = open(outfile, "wt") fd.write('''SQL Log %s%s''' % (request.path, html)) fd.close() return response