Подтвердить что ты не робот

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

Как использовать панель инструментов отладки для отладки вызовов tastypie api?
(например, я хотел бы посмотреть, сколько запросов sql выполняется для вызовов api.. и т.д.)

Может быть, я могу вызвать api из представлений django, но как?

4b9b3361

Ответ 1

Вот промежуточное программное обеспечение, которое я написал для аналогичных целей, которое обертывает 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

Ответ 2

В промежуточном программном пакете Django Debug на самом деле есть код, чтобы он не активировался для ответов типа non-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

Ответ 3

Я боюсь, что это невозможно. См. принятый ответ для работоспособного решения.

Вот почему ваш подход не сработал:

Панель инструментов не срабатывает, потому что ответ отсутствует в HTML. Все другие форматы не могут быть "проанализированы" промежуточным программным обеспечением панели инструментов, чтобы включить панель инструментов.

Вы можете добавить свои собственные инструменты, чтобы показывать SQL-запросы. Взгляните на этот простой фрагмент: http://djangosnippets.org/snippets/161/ Или вы можете использовать стороннее приложение для этого, например django-snippetscream.

Например, вы можете проверить, есть ли DEBUG is True и добавить эту информацию в объект "meta", возвращенный Tastypie.

Кроме того, взгляните на ведение журнала SQL в консоли (servererver). Некоторый полезный ресурс для этого: http://dabapps.com/blog/logging-sql-queries-django-13/

Ответ 4

Попробуйте https://github.com/django-debug-toolbar/django-debug-toolbar/pull/253

pip install git+https://github.com/caktus/[email protected]#egg=django-debug-toolbar

Это позволит панели инструментов отладки отображать информацию о запросе на вызывающей странице.

В качестве альтернативы, если вы хотите, чтобы средство визуализации HTML и ваш не слишком далеко от вашего проекта, я настоятельно рекомендую django-rest-framework

Ответ 5

@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

Вот как я это решил.
Хорошо, это не автоматическое, но сейчас все будет сделано.

Ответ 6

Я исправил это, восстановив django 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