framework django debugging tastypie

framework - ¿Cómo usar django-debug-toolbar para django-tastypie?



tastypie github (7)

django-debug-toolbar necesita que su salida sea html, pero el formato de salida predeterminado de django-tastypie es json.

Intenté enviar http://localhost/api/v1/resource/?format=html pero dice: Sorry, not implemented yet. Please append "?format=json" to your URL Sorry, not implemented yet. Please append "?format=json" to your URL

Aunque este documento enumera html como una opción válida, dice que está en la TODO list .
http://django-tastypie.readthedocs.org/en/latest/serialization.html#to-html

¿Cómo uso la barra de herramientas de depuración para depurar las llamadas de la API de tastypie?
(por ejemplo, me gustaría ver cuántas consultas de SQL se están ejecutando para las llamadas a la API ... y así sucesivamente)

Tal vez pueda llamar a la api desde las vistas de django pero ¿cómo?


Aquí hay un middleware que escribí para propósitos similares que envuelve a json en HTML para habilitar la barra de herramientas de depuración y también la imprime. Además, soporta datos binarios. No estoy usando tastypie, pero creo que debería funcionar con eso también.

# 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 1.10 introdujo el ''nuevo estilo de middleware'': https://docs.djangoproject.com/en/2.0/releases/1.10/#new-style-middleware

Esta es una nueva versión de middleware de estilo:

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


El middleware de la barra de herramientas de depuración de Django en realidad tiene un código para evitar que se active para respuestas de tipo no html como las devueltas por TastyPie. Lo que he hecho en el pasado es crear un poco de middleware que convierte las respuestas de json en HTML para que la barra de herramientas se active y pueda contar las consultas, etc. Es un poco difícil, pero hace un buen trabajo y es fácil para encender / apagar.

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


Lo arreglé reconstruyendo django snippest desde 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


Pruebe 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

Esto permitirá que la barra de herramientas de depuración muestre información sobre la solicitud en la página de llamada.

Alternativamente, si desea un renderizador HTML y no está demasiado lejos en su proyecto, le recomiendo django-rest-framework


Me temo que eso no es posible. Vea la respuesta aceptada para una solución viable.

Aquí es por qué su enfoque no funcionó:

La barra de herramientas no se activa porque la respuesta no está en HTML . Todos los demás formatos no pueden ser "analizados" por el middleware de la barra de herramientas para incluir la barra de herramientas.

Sin embargo, puede agregar sus propias herramientas para mostrar consultas SQL. Eche un vistazo a este simple fragmento de código: http://djangosnippets.org/snippets/161/ O puede usar una aplicación de terceros para esto, como django-snippetscream .

Por ejemplo, puede verificar si DEBUG is True y agregar esta información al objeto "meta" devuelto por Tastypie.

Además, eche un vistazo al registro de SQL en su consola (runserver). Algunos recursos útiles para esto: http://dabapps.com/blog/logging-sql-queries-django-13/


@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

Así lo resolví.
Ok, no es automático, pero lo hará por ahora.