Debugging Django

19
Debugging Django Simon Willison DJUGL, 19th May 2008

description

Full write-up here: http://simonwillison.net/2008/May/22/debugging/

Transcript of Debugging Django

Page 1: Debugging Django

Debugging Django

Simon WillisonDJUGL, 19th May 2008

Page 2: Debugging Django

This talk is not about

Test Driven Development

http://www.flickr.com/photos/alikaragoz/209296304/

Page 3: Debugging Django

This talk is about

Bug Driven Development

Page 5: Debugging Django

Make the most of the error page

Print statements and logging

Using the debugger

Catching errors in production

Abusing the Test Client

Page 6: Debugging Django

The Django error page

It’s not just for errors!

Trigger it explicitly with “assert False”

Show a value with “assert False, variable”

Page 7: Debugging Django
Page 8: Debugging Django

Logging to your console

def index(req): print "Hello there!"

[19/May/2008 18:14:39] "GET /static/css/img/djangosite80x15.gif HTTP/1.1" 304 0[19/May/2008 18:14:39] "GET /static/css/img/purple-gradient.png HTTP/1.1" 304 0Hello there![19/May/2008 18:14:47] "GET / HTTP/1.1" 200 12570

Page 9: Debugging Django

Logging to your console

# in settings.pyimport logginglogging.basicConfig( level = logging.DEBUG, format = '%(asctime)s %(levelname)s %(message)s',)

# Anywhere elseimport logginglogging.debug("A log message")

Page 10: Debugging Django

Logging to a file# in settings.pyimport logginglogging.basicConfig( level = logging.DEBUG, format = '%(asctime)s %(levelname)s %(message)s', filename = '/tmp/dango.log', filemode = 'w')

# Anywhere elseimport logginglogging.debug("A log message")

$ tail -f /tmp/django.log

Page 11: Debugging Django

Logging the calling context

import logging, traceback, pprint

def my_buggy_function(arg): context = pprint.pformat(traceback.extract_stack()) logging.debug(context)

Page 12: Debugging Django

Using the debugger

import pdb; pdb.set_trace()

$ python -i ./manage.py ......>>> import pdb; pdb.pm()

Page 13: Debugging Django

Errors in production

# Receive 500 error e-mails if not DEBUGADMINS = ( ('Simon Willison', '[email protected]'),)

# Receive 404 e-mails if SEND_BROKEN_LINK_EMAILSMANAGERS = ( ...)IGNORABLE_404_ENDS = ('.php', '.cgi')

Two misleadingly-named settings:

Page 14: Debugging Django

Errors over XMPP

Page 15: Debugging Django

db-error-log

Page 16: Debugging Django

Custom error middlewareclass DBLogMiddleware(object): def process_exception(self, request, exception): server_name = socket.gethostname() tb_text = traceback.format_exc() class_name = exception.__class__.__name__ ...

# in settings.pyMIDDLEWARE_CLASSES = ( ..., 'djangodblog.DBLogMiddleware',)

Page 17: Debugging Django

More useful middleware

ProfilerMiddleware

See profiler output with url?prof

DebugFooter

SQL and templates logged in footer

Page 18: Debugging Django

Abusing the test client

from django.test.utils import setup_test_environmentsetup_test_environment()

from django.test.client import Clientc = Client()

r = c.get('/2008/speaking/')print rr.templater.context