script debug app python django debugging

python - debug - ¿Cómo depurar en Django, la buena manera?



pdb debug python (27)

Entonces, comencé a aprender a codificar en Python y más tarde en Django . Las primeras veces fue difícil mirar las trazas y realmente averiguar qué hice mal y dónde estaba el error de sintaxis. Ha pasado algún tiempo y en el camino, creo que tengo una rutina para depurar mi código Django. Como esto se hizo al principio de mi experiencia de codificación, me senté y me pregunté si la forma en que lo estaba haciendo era ineficaz y podría hacerse más rápido. Por lo general, consigo encontrar y corregir los errores en mi código, pero me pregunto si debería hacerlo más rápido.

Usualmente solo uso la información de depuración que Django da cuando está habilitado. Cuando las cosas terminan como pensé, rompería mucho el flujo de código con un error de sintaxis y observaría las variables en ese punto del flujo para averiguar dónde el código hace algo diferente a lo que quería.

¿Pero puede mejorarse esto? ¿Existen algunas buenas herramientas o mejores formas de depurar tu código Django?


A veces, cuando quiero explorar un método en particular y convocar a pdb es demasiado engorroso, agregaría:

import IPython; IPython.embed()

IPython.embed() inicia un shell de IPython que tiene acceso a las variables locales desde el punto donde lo llame.


Añadir import pdb; pdb.set_trace() import pdb; pdb.set_trace() en la línea correspondiente en el código de Python y ejecútelo. La ejecución se detendrá con un shell interactivo. En el shell puede ejecutar el código Python (es decir, imprimir variables) o usar comandos como:

  • c continuar la ejecución
  • n paso a la siguiente línea dentro de la misma función
  • s paso a la siguiente línea en esta función o una función llamada
  • q salir del depurador / ejecucion

También vea: https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28


Acabo de encontrar wdb ( http://www.rkblog.rk.edu.pl/w/p/debugging-python-code-browser-wdb-debugger/?goback=%2Egde_25827_member_255996401 ). Tiene una interfaz de usuario / GUI bastante agradable con todas las campanas y silbidos. El autor dice esto sobre wdb -

"Hay IDE como PyCharm que tienen sus propios depuradores. Ofrecen un conjunto de características similar o igual ... Sin embargo, para usarlos debe usar esos IDE específicos (y algunos de ellos no son gratuitos o pueden no estar disponibles para todos). plataformas). Elija la herramienta adecuada para sus necesidades ".

Pensé que sólo lo pasaría.

También es un artículo muy útil sobre los depuradores de Python: https://zapier.com/engineering/debugging-python-boss/

Finalmente , si desea ver una buena impresión gráfica de su pila de llamadas en Django, visite: https://github.com/joerick/pyinstrument . Simplemente agregue pyinstrument.middleware.ProfilerMiddleware a MIDDLEWARE_CLASSES, luego agregue? Perfil al final de la URL de solicitud para activar el generador de perfiles.

También puede ejecutar pyinstrument desde la línea de comandos o importando como un módulo.


Casi todo ha sido mencionado hasta ahora, así que solo pdb.set_trace() que en lugar de pdb.set_trace() se puede usar ipdb.set_trace () que usa iPython y, por lo tanto, es más poderoso (autocompletar y otras cosas). Esto requiere el paquete ipdb, por lo que solo necesita pip install ipdb


Como se mencionó en otras publicaciones aquí, establecer puntos de interrupción en su código y recorrer el código para ver si se comporta como esperaba es una excelente manera de aprender algo como Django hasta que tenga una idea de cómo se comporta todo, y cuál es su código. está haciendo.

Para hacer esto recomendaría usar WingIde. Al igual que otros IDEs mencionados, agradables y fáciles de usar, con un diseño agradable y también con puntos de interrupción fáciles de establecer: evalúe / modifique la pila, etc. Perfecto para visualizar lo que hace su código a medida que avanza. Soy un gran fan de eso.

También utilizo PyCharm: tiene un excelente análisis de código estático y puede ayudar a detectar problemas antes de que te des cuenta de que están ahí.

Como ya se mencionó, django-debug-toolbar es esencial - https://github.com/django-debug-toolbar/django-debug-toolbar

Y aunque no es explícitamente una herramienta de depuración o análisis, uno de mis favoritos es SQL Printing Middleware disponible de Django Snippets en https://djangosnippets.org/snippets/290/

Esto mostrará las consultas SQL que su vista ha generado. Esto le dará una buena idea de lo que está haciendo el ORM y si sus consultas son eficientes o si necesita volver a trabajar su código (o agregar almacenamiento en caché).

Me parece inestimable para controlar el rendimiento de las consultas al desarrollar y depurar mi aplicación.

Solo una sugerencia más: lo modifiqué ligeramente para mi propio uso para mostrar solo el resumen y no la declaración SQL ... Por lo tanto, siempre lo uso mientras se desarrolla y prueba. También agregué que si el len (connection.queries) es mayor que un umbral predefinido, muestra una advertencia adicional.

Luego, si veo que algo malo (desde una perspectiva de rendimiento o de número de consultas) está sucediendo, vuelvo a la visualización completa de las declaraciones SQL para ver exactamente lo que está sucediendo. Muy útil cuando estás trabajando en un proyecto grande de Django con múltiples desarrolladores.


Desde mi perspectiva, podríamos dividir las tareas comunes de depuración de código en tres patrones de uso distintos:

  1. Algo ha provocado una excepción : el depurador Werkzeug de django-extensions ''al rescate. La capacidad de ejecutar código personalizado en todos los niveles de rastreo es un asesino. Y si está completamente atascado, puede crear un Gist para compartir con solo un clic.
  2. La página está renderizada, pero el resultado es incorrecto : de nuevo, Werkzeug mece. Para crear un punto de interrupción en el código, simplemente escriba assert False en el lugar donde desea detenerse.
  3. El código funciona mal , pero el vistazo rápido no ayuda. Probablemente, un problema algorítmico. Suspiro. Entonces usualmente pudb un depurador de consola pudb : import pudb; pudb.set_trace() import pudb; pudb.set_trace() . La principal ventaja sobre [i] pdb es que PuDB (mientras mira como está en los 80) hace que la configuración de expresiones de reloj personalizadas sea muy fácil. Y la depuración de un montón de bucles anidados es mucho más simple con una GUI.

Ah, sí, los problemas de las plantillas. El problema más común (para mí y mis colegas) es un contexto incorrecto: o no tienes una variable o tu variable no tiene algún atributo. Si está utilizando la barra de herramientas de depuración , simplemente inspeccione el contexto en la sección "Plantillas" o, si no es suficiente, establezca un salto en el código de sus vistas justo después de que se llene el contexto.

Así que va.


Desde mi propia experiencia, hay dos maneras:

  1. usa ipdb , que es un depurador mejorado como pdb.

    import ipdb;ipdb.set_trace()

  2. use django shell, solo use el comando de abajo. Esto es muy útil cuando está desarrollando una nueva vista.

    python manage.py shell


Durante el desarrollo, añadiendo un rápido

assert False, value

puede ayudar a diagnosticar problemas en las vistas o en cualquier otro lugar, sin la necesidad de usar un depurador.


Existen algunas herramientas que cooperan bien y pueden facilitar la tarea de depuración.

Lo más importante es la barra de herramientas de depuración de Django .

Entonces necesitas un buen registro usando la función de logging Python. Puede enviar la salida de registro a un archivo de registro, pero una opción más fácil es enviar la salida de registro a firepython . Para usar esto necesitas usar el navegador Firefox con la extensión firebug . Firepython incluye un complemento de firebug que mostrará cualquier registro del lado del servidor en una pestaña de Firebug.

Firebug en sí también es fundamental para depurar el lado de Javascript de cualquier aplicación que desarrolles. (Suponiendo que tenga algún código JS, por supuesto).

También me gustó django-viewtools para depurar vistas interactivamente usando pdb, pero no lo uso mucho.

Hay herramientas más útiles, como la topadora para rastrear las fugas de memoria (también hay otras buenas sugerencias dadas en las respuestas aquí en SO para el seguimiento de memoria)


Hay muchas maneras de hacerlo, pero la más sencilla es usar simplemente el depurador de Python . Solo agregue la siguiente línea en una función de vista de Django:

import pdb; pdb.set_trace()

Si intenta cargar esa página en su navegador, el navegador se bloqueará y obtendrá un aviso para continuar con la depuración del código de ejecución real.

Sin embargo hay otras opciones (no las estoy recomendando):

* return HttpResponse({variable to inspect}) * print {variable to inspect} * raise Exception({variable to inspect})

Pero el depurador de Python (pdb) es altamente recomendado para todos los tipos de código de Python. Si ya estás en pdb, también querrás echar un vistazo a la IPDB que usa ipython para la depuración.

Algunas extensiones más útiles para pdb son

pdb++ , sugerido por Antash .

pudb , sugerido por PatDuJour .

Usando el depurador de Python en Django , sugerido por Seafangs .


He empujado django-pdb a django-pdb . Es una aplicación simple que significa que no necesita editar su código fuente cada vez que quiera ingresar a pdb.

La instalación es sólo ...

  1. pip install django-pdb
  2. Agregue ''django_pdb'' a su INSTALLED_APPS

Ahora puede ejecutar: manage.py runserver --pdb para ingresar en pdb al inicio de cada vista ...

bash: manage.py runserver --pdb Validating models... 0 errors found Django version 1.3, using settings ''testproject.settings'' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C. GET / function "myview" in testapp/views.py:6 args: () kwargs: {} > /Users/tom/github/django-pdb/testproject/testapp/views.py(7)myview() -> a = 1 (Pdb)

Y ejecute: manage.py test --pdb para dividir pdb en fallas / errores de prueba ...

bash: manage.py test testapp --pdb Creating test database for alias ''default''... E ====================================================================== >>> test_error (testapp.tests.SimpleTest) ---------------------------------------------------------------------- Traceback (most recent call last): File ".../django-pdb/testproject/testapp/tests.py", line 16, in test_error one_plus_one = four NameError: global name ''four'' is not defined ====================================================================== > /Users/tom/github/django-pdb/testproject/testapp/tests.py(16)test_error() -> one_plus_one = four (Pdb)

El proyecto está alojado en GitHub , las contribuciones son bienvenidas, por supuesto.


La forma más fácil de depurar python, especialmente para los programadores que están acostumbrados a Visual Studio, es usar PTVS (Python Tools para Visual Studio). Los pasos son simples:

  1. Descárgalo e instálalo desde http://pytools.codeplex.com/
  2. Establecer puntos de interrupción y presionar F5.
  3. Su punto de interrupción se ha alcanzado, puede ver / cambiar las variables tan fácilmente como depurando programas de C # / C ++.
  4. Eso es todo :)

Si desea depurar Django usando PTVS, necesita hacer lo siguiente:

  1. En Configuración del proyecto - pestaña General, configure "Archivo de inicio" en "manage.py", el punto de entrada del programa Django.
  2. En Configuración del proyecto - pestaña Depurar, configure "Argumentos de secuencia de comandos" en "runserver --noreload". El punto clave es el "--noreload" aquí. Si no lo establece, sus puntos de interrupción no serán alcanzados.
  3. Disfrútala.

La mayoría de las opciones ya están mencionadas. Para imprimir el contexto de la plantilla, he creado una biblioteca simple para eso. Ver https://github.com/edoburu/django-debugtools

Puede usarlo para imprimir el contexto de la plantilla sin ninguna construcción {% load %} :

{% print var %} prints variable {% print %} prints all

Utiliza un formato de impresión personalizado para mostrar las variables en una etiqueta <pre> .


Me parece que Visual Studio Code es genial para depurar las aplicaciones de Django. Los parámetros estándar de python launch.json ejecutan python manage.py con el depurador adjunto, por lo que puede establecer puntos de interrupción y recorrer su código como desee.


Para aquellos que accidentalmente pueden agregar pdb a las confirmaciones en vivo, puedo sugerir esta extensión de respuesta #Koobz:

@register.filter def pdb(element): from django.conf import settings if settings.DEBUG: import pdb pdb.set_trace() return element


Realmente me gusta el depurador interactivo de Werkzeug . Es similar a la página de depuración de Django, excepto que obtienes un shell interactivo en cada nivel del rastreo. Si usas las django-extensions , obtienes un comando runserver_plus que inicia el servidor de desarrollo y te da el depurador de Werkzeug en las excepciones.

Por supuesto, solo debe ejecutar esto localmente, ya que le otorga a cualquier persona con un navegador los derechos para ejecutar un código de pitón arbitrario en el contexto del servidor.


Recomiendo encarecidamente epdb (Extended Python Debugger).

https://bitbucket.org/dugan/epdb

Una cosa que me encanta de epdb para depurar Django u otros servidores web de Python es el comando epdb.serve (). Esto establece una traza y sirve esto en un puerto local al que puede conectarse. Caso de uso típico:

Tengo una opinión de que quiero ir paso a paso. Insertaré lo siguiente en el punto en el que quiera establecer la traza.

import epdb; epdb.serve()

Una vez que este código se ejecuta, abro un intérprete de Python y me conecto a la instancia de servicio. Puedo analizar todos los valores y recorrer el código utilizando los comandos estándar de pdb como n, s, etc.

In [2]: import epdb; epdb.connect() (Epdb) request <WSGIRequest path:/foo, GET:<QueryDict: {}>, POST:<QuestDict: {}>, ... > (Epdb) request.session.session_key ''i31kq7lljj3up5v7hbw9cff0rga2vlq5'' (Epdb) list 85 raise some_error.CustomError() 86 87 # Example login view 88 def login(request, username, password): 89 import epdb; epdb.serve() 90 -> return my_login_method(username, password) 91 92 # Example view to show session key 93 def get_session_key(request): 94 return request.session.session_key 95

Y mucho más que usted puede aprender sobre cómo escribir la ayuda de epdb en cualquier momento.

Si desea servir o conectarse a varias instancias de epdb al mismo tiempo, puede especificar el puerto para escuchar (el valor predeterminado es 8080). Es decir

import epdb; epdb.serve(4242) >> import epdb; epdb.connect(host=''192.168.3.2'', port=4242)

el host por defecto es ''localhost'' si no se especifica. Lo lancé aquí para demostrar cómo puede usar esto para depurar algo que no sea una instancia local, como un servidor de desarrollo en su LAN local. Obviamente, si lo hace, tenga cuidado de que la traza establecida nunca llegue a su servidor de producción.

Como nota rápida, aún puede hacer lo mismo que la respuesta aceptada con epdb ( import epdb; epdb.set_trace() ) pero quería resaltar la funcionalidad de servicio ya que me parece muy útil.




Un poco rápido para las etiquetas de plantillas:

@register.filter def pdb(element): import pdb; pdb.set_trace() return element

Ahora, dentro de una plantilla puede hacer {{ template_var|pdb }} e ingresar una sesión pdb (dado que está ejecutando el servidor de desarrollo local) donde puede inspeccionar el element al contenido de su corazón.

Es una forma muy agradable de ver qué le ha pasado a su objeto cuando llega a la plantilla.


Una de las mejores opciones para depurar el código Django es a través de wdb: https://github.com/Kozea/wdb

wdb trabaja con python 2 (2.6, 2.7), python 3 (3.2, 3.3, 3.4, 3.5) y pypy. Aún mejor, es posible depurar un programa python 2 con un servidor wdb ejecutándose en python 3 y viceversa, o depurar un programa ejecutándose en una computadora con un servidor de depuración ejecutándose en otra computadora dentro de una página web en una tercera computadora. Aún mejor, ahora es posible pausar un proceso / subproceso de Python que se ejecuta actualmente mediante la inyección de código desde la interfaz web. (Esto requiere gdb y ptrace habilitado) En otras palabras, es una versión muy mejorada de pdb directamente en su navegador con buenas características.

Instala y ejecuta el servidor, y en tu código agrega:

import wdb wdb.set_trace()

Según el autor, las principales diferencias con respecto a pdb son:

Para aquellos que no conocen el proyecto, wdb es un depurador de Python como pdb, pero con un front-end de Web pulido y muchas características adicionales, como:

  • Resaltado de sintaxis de origen
  • Puntos de interrupción visuales
  • Completar código interactivo utilizando jedi
  • Puntos de ruptura persistentes
  • Inspección profunda de objetos utilizando el mouse. Multiproceso / multiprocesamiento.
  • Depuración remota
  • Ver expresiones
  • En edición de código del depurador.
  • Integración de servidores web populares para romper en error
  • En excepción de la interrupción durante el seguimiento (no post-mortem) en contra del depurador werkzeug, por ejemplo
  • Interrumpir los programas actualmente en ejecución mediante la inyección de código (en sistemas compatibles)

Tiene una gran interfaz de usuario basada en navegador. Una alegría de usar! :)


Una sugerencia adicional.

Puede aprovechar las pruebas de nos y pdb juntos, en lugar de inyectar pdb.set_trace() en sus vistas manualmente. La ventaja es que puede observar condiciones de error cuando se inician por primera vez, potencialmente en un código de terceros.

Aquí hay un error para mí hoy.

TypeError at /db/hcm91dmo/catalog/records/ render_option() argument after * must be a sequence, not int .... Error during template rendering In template /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/crispy_forms/templates/bootstrap3/field.html, error at line 28 render_option() argument after * must be a sequence, not int 18 19 {% if field|is_checkboxselectmultiple %} 20 {% include ''bootstrap3/layout/checkboxselectmultiple.html'' %} 21 {% endif %} 22 23 {% if field|is_radioselect %} 24 {% include ''bootstrap3/layout/radioselect.html'' %} 25 {% endif %} 26 27 {% if not field|is_checkboxselectmultiple and not field|is_radioselect %} 28 {% if field|is_checkbox and form_show_labels %}

Ahora, sé que esto significa que engañé al constructor por la forma, e incluso tengo una buena idea de qué campo es un problema. Pero, ¿puedo usar pdb para ver de qué formas crujientes se están quejando, dentro de una plantilla ?

Si puedo. Usando la opción --pdb en las pruebas de nos:

tests$ nosetests test_urls_catalog.py --pdb

Tan pronto como llego a una excepción (incluidas las que se manejan con gracia), pdb se detiene donde ocurre y puedo mirar a mi alrededor.

File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 537, in __str__ return self.as_widget() File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 593, in as_widget return force_text(widget.render(name, self.value(), attrs=attrs)) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 513, in render options = self.render_options(choices, [value]) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 543, in render_options output.append(self.render_option(selected_choices, *option)) TypeError: render_option() argument after * must be a sequence, not int INFO lib.capture_middleware log write_to_index(http://localhost:8082/db/hcm91dmo/catalog/records.html) INFO lib.capture_middleware log write_to_index:end > /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py(543)render_options() -> output.append(self.render_option(selected_choices, *option)) (Pdb) import pprint (Pdb) pprint.PrettyPrinter(indent=4).pprint(self) <django.forms.widgets.Select object at 0x115fe7d10> (Pdb) pprint.PrettyPrinter(indent=4).pprint(vars(self)) { ''attrs'': { ''class'': ''select form-control''}, ''choices'': [[(''_'', ''any type''), (7, (7, ''type 7'', ''RECTYPE_TABLE''))]], ''is_required'': False} (Pdb)

Ahora, está claro que mi elección de argumentos para el constructor de campo crujiente era como una lista dentro de una lista, en lugar de una lista / tupla de tuplas.

''choices'': [[(''_'', ''any type''), (7, (7, ''type 7'', ''RECTYPE_TABLE''))]]

Lo bueno es que este pdb se está produciendo dentro del código de Crispy, no en el mío y no tuve que insertarlo manualmente.


Uso PyCharm y diferentes herramientas de depuración. También tenga un buen conjunto de artículos sobre cómo configurar fácilmente esas cosas para principiantes. Puedes empezar aquí. Le informa sobre la depuración de PDB y GUI en general con proyectos Django. Espero que alguien se beneficie de ellos.


Uso pyDev con Eclipse realmente bueno, establezco puntos de ruptura, paso en el código, veo valores en cualquier objeto y variable, pruébalo.


Utilizo PyCharm y lo apoyo todo el tiempo. Me costó un poco, pero tengo que decir que la ventaja que obtengo no tiene precio. Intenté depurar desde la consola y le doy mucho crédito a la gente que puede hacer eso, pero para mí poder depurar visualmente mi (s) aplicación (es) es genial.

Tengo que decir, sin embargo, PyCharm tiene mucha memoria. Pero, de nuevo, nada bueno es gratis en la vida. Acaban de llegar con su última versión 3. También funciona muy bien con Django, Flask y Google AppEngine. Así que, en general, diría que es una herramienta muy útil para cualquier desarrollador.

Si aún no lo está utilizando, recomiendo obtener la versión de prueba durante 30 días para echar un vistazo al poder de PyCharm. Estoy seguro de que hay otras herramientas también disponibles, como Aptana. Pero supongo que también me gusta la forma en que se ve PyCharm. Me siento muy cómodo depurando mis aplicaciones allí.


Yo uso PyCharm (el mismo motor pydev que eclipse). Realmente me ayuda a visualmente ser capaz de pasar por mi código y ver qué está sucediendo.


utiliza pdb o ipdb . La diferencia entre estos dos es que ipdb es compatible con autocompletar.

para pdb

import pdb pdb.set_trace()

para ipdb

import ipdb ipdb.set_trace()

Para ejecutar la nueva línea, n tecla n , para continuar presionando la tecla c . Ver más opciones usando help(pdb)