Как использовать django-debug-toolbar для django-tastypie?
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
как использовать панель инструментов отладки для отладки вызовов api tastypie?
(например, я хотел бы посмотреть, сколько sql выполняются запросы для вызовов api.. и так далее)
может быть, я могу вызвать api из представлений django, но как?
7 ответов
вот промежуточное ПО, которое я написал для аналогичных целей, которое обертывает json в HTML для включения панели инструментов отладки, а также довольно печатает его. Кроме того, он поддерживает двоичные данные. Я не использую 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
промежуточное ПО панели инструментов отладки Django на самом деле имеет код, чтобы предотвратить его активацию для ответов типа не html, таких как ответы, возвращаемые 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
боюсь, что это невозможно. см. принятый ответ для работоспособного решения.
вот почему ваш подход не работает:
панель инструментов не срабатывает, потому что ответ не в HTML. Все остальные форматы не могут быть "проанализированы" промежуточным программным обеспечением панели инструментов для включения панели инструментов.
вы можете добавить свои собственные инструменты, чтобы показать SQL-запросы. Взгляните на этот простой фрагмент: http://djangosnippets.org/snippets/161/ или можно использовать стороннее приложение для этого, как django-snippetscream.
например, вы можете проверить, если DEBUG is True
и добавьте эту информацию в объект "meta", возвращаемый Tastypie.
кроме того, взгляните на ведение журнала SQL в консоли (runserver). Некоторые полезные ресурсы для этого:http://dabapps.com/blog/logging-sql-queries-django-13/
попробуйте 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
@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
вот как я ее решила.
Хорошо, это не автоматически, но пока сойдет.
Я установил, что, перестроив Джанго snippest от 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 1.10 представил "новое промежуточное ПО стиля":https://docs.djangoproject.com/en/2.0/releases/1.10/#new-style-middleware
Это новый стиль 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