django-debug-toolbar需要输出为html,但是django-tastypie的默认输出格式是json。
我尝试发送http://localhost/api/v1/resource/?format=html
,但它说Sorry, not implemented yet. Please append "?format=json" to your URL
即使此文档将html列为有效选项之一,它也会在TODO list
上说明
http://django-tastypie.readthedocs.org/en/latest/serialization.html#to-html
如何使用调试工具栏调试tastypie api调用?
(例如,我想看看为api调用运行了多少个sql查询..等等)
也许我可以从django视图中调用api但是如何?
答案 0 :(得分:35)
这是我为类似目的编写的中间件,它将HTML中的json包装起来以启用调试工具栏并且还可以打印它。此外,它支持二进制数据。我没有使用tastypie,但我认为它也应该适用。
# 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
答案 1 :(得分:8)
Django调试工具栏的中间件实际上有代码,以防止它被激活为非类型的响应,如TastyPie返回的响应。我过去所做的是创建一些中间件,将json响应转换为HTML,这样工具栏就会被激活,我可以计算查询等......这有点像黑客但是它可以完成工作并且很容易打开/关闭。
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
答案 2 :(得分:2)
我担心这是不可能的。请参阅已接受的答案以获得可行的解决方案。
这就是为什么你的方法不起作用的原因:
由于答案is not in HTML,工具栏无法启动。工具栏的中间件无法“解析”所有其他格式以包含工具栏。
您可以添加自己的工具来显示SQL查询。看看这个简单的代码段:http://djangosnippets.org/snippets/161/或者您可以使用第三方应用,例如django-snippetscream。
例如,您可以检查是否DEBUG is True
并将此信息添加到Tastypie返回的“meta”对象中。
另外,请查看控制台(runserver)中的SQL日志记录。一些有用的资源:http://dabapps.com/blog/logging-sql-queries-django-13/
答案 3 :(得分:1)
尝试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
这将允许调试工具栏在调用页面上显示有关请求的信息。
或者,如果你想要一个HTML渲染器并且不太喜欢你的项目,我强烈推荐 django-rest-framework
答案 4 :(得分: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
这就是我解决它的方法 好吧,这不是自动的,但现在会做。
答案 5 :(得分:1)
我通过从http://djangosnippets.org/snippets/344/
重建django snippest来解决这个问题"""
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
答案 6 :(得分:1)
Django 1.10推出了&#39;新式中间件&#39;:https://docs.djangoproject.com/en/2.0/releases/1.10/#new-style-middleware
这是一种新的中间件版本:
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
答案 7 :(得分:0)
在Django Debug Toolbar的3.1版中,有一个History Panel,不需要用html包装JSON响应。