Как использовать 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