40👍
Here is a middleware I wrote for similar purposes that wraps json in HTML for enabling the debug toolbar and also pretty prints it. Furthermore, it supports binary data. I’m not using tastypie, but I think it should work with that too.
# settings-dev.py
from django.http import HttpResponse
import json
MIDDLEWARE_CLASSES += (
'debug_toolbar.middleware.DebugToolbarMiddleware',
'NonHtmlDebugToolbarMiddleware',
)
class NonHtmlDebugToolbarMiddleware(object):
"""
The Django Debug Toolbar usually only works for views that return HTML.
This middleware wraps any non-HTML response in HTML if the request
has a 'debug' query parameter (e.g. http://localhost/foo?debug)
Special handling for json (pretty printing) and
binary data (only show data length)
"""
@staticmethod
def process_response(request, response):
if request.GET.get('debug') == '':
if response['Content-Type'] == 'application/octet-stream':
new_content = '<html><body>Binary Data, ' \
'Length: {}</body></html>'.format(len(response.content))
response = HttpResponse(new_content)
elif response['Content-Type'] != 'text/html':
content = response.content
try:
json_ = json.loads(content)
content = json.dumps(json_, sort_keys=True, indent=2)
except ValueError:
pass
response = HttpResponse('<html><body><pre>{}'
'</pre></body></html>'.format(content))
return response
8👍
The Django Debug Toolbar’s middleware actually has code in it to prevent it being activated for non-html type responses like those returned by TastyPie. What I have done in the past is create a bit of middleware that converts json responses into HTML so the toolbar will be activated and I can count queries etc… It is a bit of a hack but it gets to job done and is easy to turn on/off.
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
- [Django]-UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 2: ordinal not in range(128)
- [Django]-Nested blocks in Django templates
- [Django]-Testing Python Decorators?
3👍
Django 1.10 introduced ‘new style middleware’: https://docs.djangoproject.com/en/2.0/releases/1.10/#new-style-middleware
This is a new style middleware version:
import json
from django.http import HttpResponse
class NonHtmlDebugToolbarMiddleware:
"""
The Django Debug Toolbar usually only works for views that return HTML.
This middleware wraps any non-HTML response in HTML if the request
has a 'debug' query parameter (e.g. http://localhost/foo?debug)
Special handling for json (pretty printing) and
binary data (only show data length)
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
if response['Content-Type'] == 'application/json':
content = response.content
try:
json_ = json.loads(content)
content = json.dumps(json_, sort_keys=True, indent=2)
except ValueError:
pass
response = HttpResponse('<html><body><pre>{}'
'</pre></body></html>'.format(content),
content_type='text/html')
return response
- [Django]-How do I return a 401 Unauthorized in Django?
- [Django]-Want to disable signals in Django testing
- [Django]-Django can' t load Module 'debug_toolbar': No module named 'debug_toolbar'
2👍
I’m afraid that’s not possible. See the accepted answer for a workable solution.
Here’s why your approach did not work:
The toolbar does not kick-in because the answer is not in HTML. All other formats can’t be “parsed” by the toolbar’s middleware to include the Toolbar.
You can add your own tools to show SQL queries though. Take a look at this simple snippet: http://djangosnippets.org/snippets/161/ Or you can use a third party app for this, like django-snippetscream.
For example, you could check if DEBUG is True
and add this info to the “meta” object returned by Tastypie.
Also, take a look at the SQL logging in your console (runserver). Some useful resource for this: http://dabapps.com/blog/logging-sql-queries-django-13/
- [Django]-Add Python Application to accept incoming network connections
- [Django]-Django: Get model from string?
- [Django]-Showing custom model validation exceptions in the Django admin site
1👍
Try https://github.com/django-debug-toolbar/django-debug-toolbar/pull/253
pip install git+https://github.com/caktus/django-debug-toolbar@ajax-panel#egg=django-debug-toolbar
This will allow debug toolbar to display information about the request on the calling page.
Alternatively if you want an HTML renderer and your not too far into your project, I highly recommend django-rest-framework
- [Django]-Python/Django: How to remove extra white spaces & tabs from a string?
- [Django]-Django load block for css
- [Django]-How can I perform Django's `syncdb –noinput` with call_command?
1👍
@html_decorator
def test(request):
view = resolve("/api/v1/albumimage/like/user/%d/" % 2 )
accept = request.META.get("HTTP_ACCEPT")
accept += ",application/json"
request.META["HTTP_ACCEPT"] = accept
res = view.func(request, **view.kwargs)
return HttpResponse(res._container)
def html_decorator(func):
"""
wrap it inside html
"""
def _decorated(*args, ** kwargs):
response = func(*args, **kwargs)
wrapped = ("<html><body>",
response.content,
"</body></html>")
return HttpResponse(wrapped)
return _decorated
This is how I solved it.
Ok it’s not automatic, but will do for now.
- [Django]-InvalidBasesError: Cannot resolve bases for [<ModelState: 'users.GroupProxy'>]
- [Django]-Django-nonrel + Django-registration problem: unexpected keyword argument 'uidb36' when resetting password
- [Django]-Django – convert a list back to a queryset
1👍
I fixed that by rebuilding django snippest from http://djangosnippets.org/snippets/344/
"""
Database and request debug info for Tastypie.
Based of idea from http://djangosnippets.org/snippets/344/
# settings.py:
DEBUG=True
DEBUG_SQL=True
MIDDLEWARE_CLASSES = (
'YOURPATH.SQLLogMiddleware.SQLLogMiddleware',
'django.middleware.transaction.TransactionMiddleware',
...)
"""
# Python
import time
import logging
import json
# Django
from django.conf import settings
from django.db import connection
class SQLLogMiddleware:
"""\
Attach debug information to result json.
"""
def process_request(self, request):
request.sqllog_start = time.time()
def process_response (self, request, response):
# request.sqllog_start is empty if an append slash redirect happened.
debug_sql = getattr(settings, "DEBUG_SQL", False)
if not getattr(request, 'sqllog_start', False):
return response
if (not request.sqllog_start) or not (settings.DEBUG and debug_sql):
return response
try:
content = json.loads(response.content)
except ValueError:
return response
timesql = 0.0
for query in connection.queries:
timesql += float(query['time'])
seen = {}
duplicate = 0
for query in connection.queries:
sql = query["sql"]
c = seen.get(sql, 0)
if c:
duplicate += 1
if c:
query["seen"] = c + 1
seen[sql] = c + 1
timerequest = round(time.time() - request.sqllog_start, 3)
queries = connection.queries
debug = {'request_path': request.path,
'query_count': len(queries),
'duplicate_query_count': duplicate,
'sql_execute_time': timesql,
'request_execution_time': timerequest,
'queries': []}
for query in queries:
debug['queries'].append({'time': query['time'],
'sql': query['sql']})
content['debug'] = debug
response.content = json.dumps(content)
logging.info(debug)
return response
- [Django]-Change Django Templates Based on User-Agent
- [Django]-How do I remove Label text in Django generated form?
- [Django]-Django i18n: Common causes for translations not appearing
0👍
With version 3.1 of the Django Debug Toolbar, there is a History Panel which removes the need to wrap the JSON responses with html.
- [Django]-Cron and virtualenv
- [Django]-AttributeError: 'Settings' object has no attribute 'ROOT_URLCONF'
- [Django]-What's the correct way to set up Django translation?