Login

Template Query Debug

Author:
insin
Posted:
March 8, 2007
Language:
HTML/template
Version:
Not specified
Score:
79 (after 83 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 5 years, 9 months ago
  2. Bootstrap theme for django-endless-pagination? by se210 8 years, 9 months ago
  3. Bootstrap theme for django-endless-pagination? by se210 8 years, 9 months ago
  4. Reusable form template with generic view by roldandvg 8 years, 10 months ago
  5. Pagination Django with Boostrap by guilegarcia 8 years, 12 months 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!

#

Please login first before commenting.