Debugging Django & Ajax

UPDATE: See Peter’s comment below for a slightly revised (and better) version of this.


The Django Debug Toolbar is essential for developing Django applications but it comes short in one area – Ajax. There’s been progress over the last couple years but the latest pull request for a panel that supports Ajax has yet to be completed and merged. This leaves you pretty much in the dark when making XHR requests as the toolbar only works if the mimetype of the response is either text/html or application/xhtml+xml and contains a closing </body> tag (otherwise your XHR requests would be filled with a bunch of junk from the toolbar).

After digging around I stumbled upon this SO post which details a few solutions including using the following middleware:

from django.conf import settings
class JsonAsHTML(object):
'''
View a JSON response in your browser as HTML
Useful for viewing stats using Django Debug Toolbar
This middleware should be place AFTER Django Debug Toolbar middleware
'''
def process_response(self, request, response):
# not for production or production like environment
if not settings.DEBUG:
return response
# do nothing for actual ajax requests
if request.is_ajax():
return response
# only do something if this is a json response
if 'application/json' in response['Content-Type'].lower():
title = 'JSON as HTML Middleware for: %s' % request.get_full_path()
response.content = '<html><head><title>%s</title></head><body>%s</body></html>' % (title, response.content)
response['Content-Type'] = 'text/html'
return response

view raw
json.py
hosted with ❤ by GitHub

Add this middleware right after the debug toolbar in your settings (and ensure that it is only enabled for your dev environment) and then load an Ajax URL directly in a browser tab. The middleware simply detects that you’re not making this request as Ajax and wraps the response in some HTML which will activate the debug toolbar. Very handy.

It’s definitely a bit of a hack and doesn’t make working with posts very easy, but it’s better than nothing.

5 thoughts on “Debugging Django & Ajax”

  1. Hi,

    I made some updates to that with this:

    """
    To use this, add::
    MIDDLEWARE_CLASSES += ('airmozilla.base.middleware.JsonAsHTML',)
    to your settings and for any AJAX request, you can open it
    separately and add `&_debug=true` to the URL.
    """
    from urllib import quote
    from django.conf import settings
    class JsonAsHTML(object): # pragma: no cover
    '''
    View a JSON response in your browser as HTML
    Useful for viewing stats using Django Debug Toolbar
    This middleware should be place AFTER Django Debug Toolbar middleware
    '''
    def process_response(self, request, response):
    # not for production or production like environment
    if not settings.DEBUG:
    return response
    # do nothing for actual ajax requests
    if request.is_ajax() or not request.GET.get('_debug'):
    return response
    # only do something if this is a json response
    if response['Content-Type'].lower().startswith('application/json'):
    title = (
    'JSON as HTML Middleware for: %s' %
    quote(request.get_full_path())
    )
    content = response.content
    content = content.replace('<', '&lt;').replace('>', '&gt;')
    response.content = (
    '<!doctype html>\n<html><head><title>%s</title>'
    '<meta content="text/html; charset=UTF-8" '
    'http-equiv="Content-Type">'
    '</head>\n<body>\n%s\n</body></html>'
    % (title, content)
    )
    response['Content-Type'] = 'text/html'
    return response

    view raw
    middleware.py
    hosted with ❤ by GitHub

    * AngularJS doesn’t send that XHR header that jQuery does
    * Proper doctype
    * UTF8 meta header
    * escape any in the content

  2. couldn’t figure out the embed, here is a link:

    """
    To use this, add::
    MIDDLEWARE += ('base.middleware.JsonAsHTML',)
    to your settings and for any AJAX request, you can open it
    separately and add `&_debug=true` to the URL.
    """
    from urllib import quote
    from django.conf import settings
    class JsonAsHTML(object): # pragma: no cover
    """
    View a JSON response in your browser as HTML
    Useful for viewing stats using Django Debug Toolbar
    This middleware should be place AFTER Django Debug Toolbar middleware
    """
    def __init__(self, get_response):
    self.get_response = get_response
    def __call__(self, request):
    response = self.get_response(request)
    # not for production or production like environment
    if not settings.DEBUG:
    return response
    # do nothing for actual ajax requests
    if request.is_ajax() or not request.GET.get('_debug'):
    return response
    # only do something if this is a json response
    if response['Content-Type'].lower().startswith('application/json'):
    title = (
    'JSON as HTML Middleware for: %s' %
    quote(request.get_full_path())
    )
    content = response.content
    content = content.replace('<', '&lt;').replace('>', '&gt;')
    response.content = (
    '<!doctype html>\n<html><head><title>%s</title>'
    '<meta content="text/html; charset=UTF-8" '
    'http-equiv="Content-Type">'
    '</head>\n<body>\n%s\n</body></html>'
    % (title, content)
    )
    response['Content-Type'] = 'text/html'
    return response

    view raw
    middleware.py
    hosted with ❤ by GitHub

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s