Login

Template Query Debug

Author:
insin
Posted:
March 8, 2007
Language:
HTML/template
Version:
Not specified
Score:
80 (after 84 ratings)

I often find something like this lurking at the end of my base templates - it'll show you which queries were run while generating the current page, but they'll start out hidden so as not to be a pain.

Of course, before this works, you'll need to satisfy all the criteria for getting debug information in your template context:

  1. Have 'django.core.context_processors.debug' in your TEMPLATE_CONTEXT_PROCESSORS setting (it was there in the default settings, last time I checked).
  2. Have your current IP in your INTERNAL_IPS setting.
  3. Use RequestContext when rendering the current template (if you're using a generic view, you're already using RequestContext).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{% if debug %}
<div id="debug">
  <h2>Queries</h2>
  <p>
    {{ sql_queries|length }} Quer{{ sql_queries|pluralize:"y,ies" }}
    {% ifnotequal sql_queries|length 0 %}
    (<span style="cursor: pointer;" onclick="var s=document.getElementById('debugQueryTable').style;s.display=s.display=='none'?'':'none';this.innerHTML=this.innerHTML=='Show'?'Hide':'Show';">Show</span>)
    {% endifnotequal %}
  </p>
  <table id="debugQueryTable" style="display: none;">
    <col width="1"></col>
    <col></col>
    <col width="1"></col>
    <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">SQL</th>
      <th scope="col">Time</th>
    </tr>
    </thead>
    <tbody>
    {% for query in sql_queries %}<tr class="{% cycle odd,even %}">
      <td>{{ forloop.counter }}</td>
      <td>{{ query.sql|escape }}</td>
      <td>{{ query.time }}</td>
    </tr>{% endfor %}
    </tbody>
  </table>
</div>
{% endif %}

More like this

  1. Bootstrap Accordian by Netplay4 7 years, 9 months ago
  2. Bootstrap theme for django-endless-pagination? by se210 10 years, 9 months ago
  3. Bootstrap theme for django-endless-pagination? by se210 10 years, 9 months ago
  4. Reusable form template with generic view by roldandvg 10 years, 10 months ago
  5. Pagination Django with Boostrap by guilegarcia 11 years ago

Comments

jdobbins (on March 11, 2007):

Thanks for the great snip! Wonderful tool for debugging 'slow pages'!

#

msgre (on March 14, 2007):

Cool!

I have little troubles with displaying long rows of queries. For example:

SELECT col1,col2,col3,col4 FROM table;

If you have a LOT of colX, they aren't wrapped in browser, and queries are bad to read.

So, I make little modification. I wrote custom filter, which replace character "," (comma) to ", " (comma and space). Now I could read debug SQL queries more comfortably.

My custom filter

def spaces_and_commas(value):
    from re import compile
    c = compile(",[^ ]")
    return c.sub(", ", value)

register.filter(spaces_and_commas)

Modification of your template (row 24)

<td>{{ query.sql|spaces_and_commas|escape }}</td>

Thank you for great snippet, insin.

#

cookiebearo (on May 28, 2007):

thank you both insin for the snippet and msgre for the filter, however, i noticed a bug with the filter

the expression:

c = compile(",[^ ]")

matches the first character after the comma (non-space), so after the sub call it is replacing that character with a space

i only caught this after realizing there was a missing " before each column

i swapped that out for:

c = compile(",(?! )")

and it seems to be working a-ok

#

PhiR (on September 12, 2007):

I'm using this snippets with the modifications in the comments but I've found useful to add this templatetags:

def slice_500(value):
    return value[:500]
register.filter(slice_500)

and to restrict the number of queries printed like this:

{% for query in sql_queries|splice_500 %}<tr class="{% cycle odd,even %}">

Some of my views are used for validation and run up to a few hundred thousand queries, which is a bit too much to print in a browser.

#

darek (on July 13, 2008):

Very helpful snippen. Tanks.

By the way... in current Django SVN version You don't have to set TEMPLATE_CONTEXT_PROCESSORS, it's on by default.

#

aaronfay (on September 24, 2008):

Brilliant works like a charm :)

af

#

ramikassab (on February 11, 2009):

Awesome snippet. Simple, clean, and effective...

#

analyzer (on March 7, 2010):

Hello,

I am new to django and i justed started to play around with django. I've copied this snippet to my base template but I can't see anything?

I checked every of the three steps mentioned above, the context processors are set by default and my ip is on INTERNAL_IPS. I don't understand what the third point means but I've added a request context to shortcut for rendering templates.

What can I do to get it work? Thanks for your help in advance and sorry for my bad english.

analyzer

#

Klaidi (on July 22, 2010):

nice !

#

Latisse-UK (on October 3, 2012):

Very useful

Latisse UK

#

m (on March 7, 2013):

I still can't get it to work. I'm using Django 1.3.1. Can someone post their settings? I had to add a number of options to TEMPLATE_CONTEXT_PROCESSORS to get my site to render correctly. ("django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.core.context_processors.static", "django.contrib.messages.context_processors.messages")

I'm not clear where the template code goes. I copied it into my admin_base.html.

#

vdboor (on October 13, 2014):

I've packed this snippet into django-debugtools. Hope that's useful for you too:

pip install django-debugtools
INSTALLED_APPS += ('debugtools',)
{% print_queries %}

For more examples, see https://github.com/edoburu/django-debugtools

#

mariorojas (on December 5, 2023):

cool!

#

Rajeev529 (on January 7, 2026):

nice

#

Please login first before commenting.