Comment déboguer dans Django, le bon moyen? [fermé]
Donc, j'ai commencé à apprendre à coder dans Python et plus tard Django . Les premières fois, il était difficile de regarder les tracebacks et de comprendre ce que j'ai fait de mal et où était l'erreur de syntaxe. Un certain temps s'est écoulé maintenant et en cours de route, je suppose que j'ai eu une routine dans le débogage de mon code Django. Comme cela a été fait au début de mon expérience de codage, je me suis assis et je me suis demandé si comment je faisais cela était inefficace et pourrait être fait plus rapidement. Je parviens généralement à trouver et à corriger le bugs dans mon code, mais je me demande si je devrais le faire plus vite?
Habituellement, J'utilise simplement les informations de débogage que Django donne lorsqu'il est activé. Quand les choses finissent comme je le pensais, je casse beaucoup le flux de code avec une erreur de syntaxe, et regarde les variables à ce moment-là dans le flux pour comprendre, où le code fait autre chose que ce que je voulais.
, Mais cela peut-il être amélioré? Existe-t-il de bons outils ou de meilleures façons de déboguer votre code Django?
27 réponses
Il y a un tas de façons de le faire, mais le plus simple est de simplement utilisez le débogueur Python . Ajoutez simplement la ligne suivante à une fonction de vue Django:
import pdb; pdb.set_trace()
Si vous essayez de charger cette page dans votre navigateur, le navigateur se bloque et vous obtenez une invite pour continuer le débogage sur le code d'exécution réel.
Cependant, il existe d'autres options (Je ne les recommande pas):
* return HttpResponse({variable to inspect})
* print {variable to inspect}
* raise Exception({variable to inspect})
Mais le débogueur Python (pdb) est fortement recommandé pour tous les types de Python code. Si vous êtes déjà dans apb, vous voulez également avoir un coup d'oeil à IPDB qui utilise ipython pour le débogage.
Une extension plus utile à pdb sont
Apb++, suggéré par Antash.
Pudb, suggéré par PatDuJour.
À l'Aide de l'Python débogueur dans Django, suggéré par Seafangs.
J'aime vraiment le débogueur interactif deWerkzeug . C'est similaire à la page de débogage de Django, sauf que vous obtenez un shell interactif à tous les niveaux du traceback. Si vous utilisez django-extensions , vous obtenez une commande de gestion runserver_plus
qui démarre le serveur de développement et vous donne le débogueur de Werkzeug sur les exceptions.
Bien sûr, vous ne devriez l'exécuter que localement, car cela donne à toute personne ayant un navigateur les droits d'exécuter du code Python arbitraire dans le contexte du serveur.
Un petit quickie pour les balises de modèle:
@register.filter
def pdb(element):
import pdb; pdb.set_trace()
return element
Maintenant, à l'intérieur d'un modèle, vous pouvez faire {{ template_var|pdb }}
et entrer une session pdb (étant donné que vous exécutez le serveur de développement local) où vous pouvez inspecter element
au contenu de votre cœur.
C'est une très belle façon de voir ce qui est arrivé à votre objet quand il arrive au modèle.
Il y a quelques outils qui coopèrent bien et peuvent faciliter votre tâche de débogage.
Le plus important est la barre D'outils Django debug .
Ensuite, vous avez besoin d'une bonne journalisation en utilisant la fonction Python logging. Vous pouvez envoyer une sortie de journalisation à un fichier journal, mais une option plus simple consiste à envoyer une sortie de journal à firepython. Pour l'utiliser, vous devez utiliser le navigateur Firefox avec le firebug extension. Firepython inclut un plugin firebug qui affichera tout connexion côté serveur dans un onglet Firebug.
Firebug lui-même est également critique pour le débogage du côté Javascript de toute application que vous développez. (En supposant que vous avez du code JS bien sûr).
J'ai aussi aimé django-viewtools pour déboguer les vues de manière interactive en utilisant pdb, mais je ne l'utilise pas beaucoup.
Il existe des outils plus utiles comme dozer pour traquer les fuites de mémoire (il y a aussi d'autres bonnes suggestions données dans les réponses ici sur SO pour le suivi de la mémoire).
Presque tout a été mentionné jusqu'à présent, donc j'ajouterai seulement qu'au lieu de pdb.set_trace()
on peut utiliser ipdb.set_trace () {[4] } qui utilise iPython et est donc plus puissant (autocomplete et autres goodies). Cela nécessite le paquet ipdb, donc vous avez seulement besoin de pip install ipdb
J'ai poussé django-pdb
à PyPI.
C'est une application simple qui signifie que vous n'avez pas besoin de modifier votre code source chaque fois que vous voulez entrer dans pdb.
L'Installation est juste...
pip install django-pdb
- ajouter
'django_pdb'
à votreINSTALLED_APPS
Vous pouvez maintenant exécuter: manage.py runserver --pdb
pour entrer dans pdb au début de chaque vue...
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)
Et exécutez: manage.py test --pdb
pour entrer dans pdb sur les échecs/erreurs de test...
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)
, Le projet est hébergé sur GitHub, contributions sont les bienvenus bien sûr.
Le moyen le plus simple de déboguer python - en particulier pour les programmeurs habitués à Visual Studio - est D'utiliser PTVS (Python Tools for Visual Studio). Les étapes sont simples:
- Téléchargez-le et installez-le depuis http://pytools.codeplex.com/
- Définissez les points d'arrêt et appuyez sur F5.
- votre point d'arrêt est atteint, vous pouvez afficher / modifier les variables aussi facilement que le débogage des programmes C#/C++.
- C'est tout :)
Si vous voulez déboguer Django à L'aide de PTV, vous devez pour faire ce qui suit:
- dans L'onglet Paramètres du projet - Général, définissez "fichier de démarrage" sur "manage.py", le point D'entrée du programme Django.
- dans L'onglet Paramètres du projet - débogage, définissez "arguments du Script" sur "runserver --noreload". Le point clé est le" -- noreload " ici. Si vous ne le définissez pas, vos points d'arrêt ne seront pas touchés.
- Profitez-en.
J'utilise PyCharm et je m'en tiens à tout le chemin. Il m'a coûté un peu, mais je dois dire que l'avantage que j'en retire c'est inestimable. J'ai essayé de déboguer à partir de la console et je donne beaucoup de crédit aux gens qui peuvent le faire, mais pour moi, pouvoir déboguer visuellement mes applications est génial.
Je dois dire cependant, PyCharm prend beaucoup de mémoire. Mais là encore, rien de bon n'est gratuit dans la vie. Ils viennent de venir avec leur dernière version 3. Il joue aussi très bien avec Django, Flask et Google AppEngine. Donc, dans l'ensemble, je dirais que c'est un excellent outil pratique pour tout développeur.
Si vous ne l'utilisez pas encore, je vous recommande d'obtenir la version d'essai pendant 30 jours pour jeter un oeil à la puissance de PyCharm. Je suis sûr qu'il existe d'autres outils également disponibles, tels que Aptana. Mais je suppose que j'aime aussi la façon dont PyCharm ressemble. Je me sens très à l'aise de déboguer mes applications là-bas.
De mon point de vue, nous pourrions décomposer les tâches communes de débogage de code en trois modèles d'utilisation distincts:
- quelque Chose a soulevé une exception: runserver_plus' Werkzeug débogueur à la rescousse. La capacité d'exécuter du code personnalisé à tous les niveaux de trace est un tueur. Et si vous êtes complètement bloqué, vous pouvez créer un essentiel à partager en un seul clic.
- la Page est rendue, mais le résultat est faux : encore une fois, Werkzeug bascule. Pour faire un point d'arrêt dans le code, tapez simplement
assert False
à l'endroit où vous voulez vous arrêter. -
le Code fonctionne mal , mais le regard rapide n'aide pas. Très probablement, un problème algorithmique. Soupir. Ensuite, je lance généralement un débogueur de console PuDB:
import pudb; pudb.set_trace()
. Le principal avantage par rapport à [i]pdb est que PuDB (tout en regardant comme vous êtes dans les années 80) rend le réglage des expressions de montre personnalisées un jeu d'enfant. Et le débogage d'un tas de boucles imbriquées est beaucoup plus simple avec une interface graphique.
Ah, oui, les malheurs des modèles. Le problème le plus commun (pour moi et mes collègues) est un mauvais contexte: soit vous n'avez pas de variable, soit votre variable n'a pas d'attribut. Si vous utilisez debug toolbar , inspectez simplement le contexte dans la section "modèles" ou, si cela ne suffit pas, définissez une pause dans le code de vos vues juste après que votre contexte est rempli.
C'est parti.
Parfois, quand je veux explorer dans une méthode particulière et invoquer pdb est trop lourd, j'ajouterais:
import IPython; IPython.embed()
IPython.embed()
démarre un shell IPython qui a accès aux variables locales à partir du point où vous l'appelez.
Je recommande fortement epdb (débogueur Python étendu).
Https://bitbucket.org/dugan/epdb
Une chose que j'aime à propos d'epdb pour déboguer Django ou d'autres serveurs Web Python est l'epdb.servir() de la commande. Cela définit une trace et le sert sur un port local auquel vous pouvez vous connecter. Cas d'utilisation typique:
J'ai une vue que je veux passer par étape par étape. Je vais insérer ce qui suit au point où je veux définir la trace.
import epdb; epdb.serve()
Une fois que ce code obtient exécuté, j'ouvre un interpréteur Python et je me connecte à l'instance de service. Je peux analyser toutes les valeurs et parcourir le code en utilisant les commandes pdb standard comme 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
Et des tonnes de plus que vous pouvez en apprendre davantage sur la saisie de l'aide epdb à tout moment.
Si vous souhaitez servir ou vous connecter à plusieurs instances epdb en même temps, vous pouvez spécifier le port sur lequel écouter (la valeur par défaut est 8080). I. e.
import epdb; epdb.serve(4242)
>> import epdb; epdb.connect(host='192.168.3.2', port=4242)
L'hôte par défaut est 'localhost' s'il n'est pas spécifié. Je l'ai jeté dans ici pour montrer comment vous pouvez l'utiliser pour déboguer autre chose qu'une instance locale, comme un serveur de développement de votre réseau local. Évidemment, si vous faites cela, veillez à ce que la trace set ne soit jamais sur votre serveur de production!
En guise de note rapide, vous pouvez toujours faire la même chose que la réponse acceptée avec epdb (import epdb; epdb.set_trace()
) mais je voulais mettre en évidence la fonctionnalité de service car je l'ai trouvée si utile.
Je viens de trouver wdb (http://www.rkblog.rk.edu.pl/w/p/debugging-python-code-browser-wdb-debugger/?goback=%2Egde_25827_member_255996401). il a une interface utilisateur / GUI assez agréable avec toutes les cloches et de sifflets. L'auteur dit ceci à propos de wdb -
"Il y a des IDE comme PyCharm qui ont leurs propres débogueurs. Ils offrent un ensemble similaire ou égal de fonctionnalités ... Cependant, pour les utiliser, vous devez utiliser ces IDE spécifiques (et certains d'entre eux sont alors non libres ou peuvent ne pas être disponibles pour tous plate). Choisissez le bon outil pour vos besoins."
Je pensais juste le transmettre.
Aussi un article très utile sur les débogueurs python: https://zapier.com/engineering/debugging-python-boss/
Enfin , si vous souhaitez voir une belle impression graphique de votre pile d'appels dans Django, checkout: https://github.com/joerick/pyinstrument . Il suffit d'ajouter pyinstrument.intergiciel.ProfilerMiddleware à MIDDLEWARE_CLASSES, puis Ajouter ?profil de l' fin de L'URL de la demande pour activer le profileur.
Peut également exécuter pyinstrument à partir de la ligne de commande ou en l'important en tant que module.
J'utilise PyCharm et différents outils de débogage. Ont également une belle articles mis sur facile mettre en place ces choses pour les novices. vous pouvez commencer ici.{[2] } Il parle du débogage PDB et GUI en général avec les projets Django. J'espère que quelqu'un en tirerait profit.
Si vous utilisez Aptana pour le développement de django, Regardez ceci: http://www.youtube.com/watch?v=qQh-UQFltJQ
Si ce n'est pas le cas, envisagez de l'utiliser.
La plupart des options sont déjà mentionnées. Pour imprimer le contexte du modèle, j'ai créé une bibliothèque simple pour cela. Voir https://github.com/edoburu/django-debugtools
Vous pouvez l'utiliser pour imprimer le contexte du modèle sans aucune construction {% load %}
:
{% print var %} prints variable
{% print %} prints all
Il utilise un format pprint personnalisé pour afficher les variables dans une balise <pre>
.
Je trouve que le Code Visual Studio est génial pour le débogage des applications Django. Le lancement python standard.les paramètres json s'exécutent python manage.py
avec le débogueur attaché, de sorte que vous pouvez définir des points d'arrêt et parcourir votre code comme vous le souhaitez.
Pour ceux qui peuvent accidentellement ajouter pdb dans les commits en direct, je peux suggérer cette extension de la réponse # Koobz:
@register.filter
def pdb(element):
from django.conf import settings
if settings.DEBUG:
import pdb
pdb.set_trace()
return element
L'une de vos meilleures options pour déboguer le code Django est via wdb: https://github.com/Kozea/wdb
WDB fonctionne avec python 2 (2.6, 2.7), python 3 (3.2, 3.3, 3.4, 3.5) et pypy. Mieux encore, il est possible de déboguer un programme python 2 avec un serveur WDB en cours d'exécution sur python 3 et vice-versa ou de déboguer un programme en cours d'exécution sur un ordinateur avec un serveur de débogage en cours d'exécution sur un autre ordinateur à l'intérieur d'une page web sur un troisième ordinateur! Encore mieux, il est maintenant possible de mettre en pause un actuellement exécution du processus/thread python en utilisant l'injection de code à partir de l'interface web. (Cela nécessite gdb et ptrace activé) En d'autres termes, il est une version très améliorée de pdb directement dans votre navigateur avec de belles fonctionnalités.
Installez et exécutez le serveur, et dans votre code ajoutez:
import wdb
wdb.set_trace()
Selon l'auteur, les principales différences par rapport à pdb
sont:
Pour ceux qui ne connaissent pas le projet, wdb est un débogueur Python comme pdb, mais avec un frontal web lisse et beaucoup des fonctionnalités supplémentaires, telles que:
- coloration syntaxique de la source
- points d'arrêt visuels
- achèvement du code interactif à l'aide de jedi
- points D'arrêt persistants
- inspection des objets profonds à l'aide de la souris multithreading / multiprocessing support
- débogage à Distance
- regarder les expressions
- dans l'édition du code du débogueur
- intégration des serveurs Web populaires à briser en cas d'erreur
- dans l'exception casser pendant la trace (pas post-mortem) contrairement au débogueur werkzeug par exemple
- briser les programmes en cours d'exécution par injection de code (sur les systèmes pris en charge)
Il a une grande interface utilisateur basée sur un navigateur. Un plaisir de l'utiliser! :)
Ajoutez import pdb; pdb.set_trace()
à la ligne correspondante dans le code Python et exécutez-le. L'exécution s'arrêtera avec un shell interactif. Dans le shell, vous pouvez exécuter du code Python (c'est-à-dire imprimer des variables) ou utiliser des commandes telles que:
-
c
continuer l'exécution -
n
étape à la ligne suivante dans la même fonction -
s
passez à la ligne suivante de cette fonction ou d'une fonction appelée -
q
quitter le débogueur / exécution
Voir Aussi: https://poweruser.blog/la configuration d'un point d'arrêt-en-python-438e23fe6b28
Je suggère fortement d'utiliser PDB.
import pdb
pdb.set_trace()
Vous pouvez inspecter toutes les valeurs des variables, intervenir dans la fonction et bien plus encore. https://docs.python.org/2/library/pdb.html
Pour vérifier tous les types de demande, de réponse et de hits à la base de données.j'utilise django-debug-toolbar https://github.com/django-debug-toolbar/django-debug-toolbar
Comme mentionné dans d'autres articles ici-définir des points d'arrêt dans votre code et parcourir le code pour voir s'il se comporte comme prévu est un excellent moyen d'apprendre quelque chose comme Django jusqu'à ce que vous ayez une bonne idée de comment tout se comporte - et ce que fait votre code.
Pour ce faire, je recommande D'utiliser WingIde. Tout comme les autres IDE mentionnés nice et facile à utiliser, Belle Mise en page et aussi facile à définir des points d'arrêt évaluer / modifier la pile, etc. Parfait pour visualiser ce que fait votre code comme vous l'étape à travers elle. Je suis un grand fan de lui.
J'utilise aussi PyCharm-il a une excellente analyse de code statique et peut parfois aider à repérer les problèmes avant de vous rendre compte qu'ils sont là.
Comme déjà mentionné django-debug-toolbar est essentiel - https://github.com/django-debug-toolbar/django-debug-toolbar
Et bien que ce ne soit pas explicitement un outil de débogage ou d'analyse - l'un de mes favoris est SQL Printing Middleware disponible à partir des extraits de Django à https://djangosnippets.org/snippets/290/
Cela affichera les requêtes SQL générées par votre vue. Cela vous donnera une bonne idée de ce que fait L'ORM et si vos requêtes sont efficaces ou si vous devez retravailler votre code (ou ajouter de la mise en cache).
Je le trouve inestimable pour garder un œil sur les performances des requêtes lors du développement et du débogage de mon application.
Juste un autre conseil-je l'ai légèrement modifié pour mon propre usage pour ne montrer que le résumé et non le L'instruction SQL.... Donc, je l'utilise toujours lors du développement et des tests. J'ai également ajouté que si le len (connexion.requêtes) est supérieure à un seuil prédéfini, il affiche un avertissement supplémentaire.
Ensuite, si je remarque quelque chose de mauvais (du point de vue de la performance ou du nombre de requêtes), je retourne sur l'affichage complet des instructions SQL pour voir exactement ce qui se passe. Très pratique lorsque vous travaillez sur un grand projet Django avec plusieurs développeurs.
Une suggestion supplémentaire.
Vous pouvez tirer parti de nosetests etpdb ensemble, plutôt que d'injecter pdb.set_trace()
dans vos vues manuellement. L'avantage est que vous pouvez observer des conditions d'erreur lors du premier démarrage, potentiellement dans le code tiers.
Voici une erreur pour moi aujourd'hui.
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 %}
Maintenant, je sais que cela signifie que j'ai gaffé le constructeur pour le formulaire, et j'ai même une bonne idée de quel champ est un problème. Mais, puis-je utiliser pdb pour voir ce qu'est croustillant forms se plaindre de, dans un modèle ?
Oui, je peux. Utilisation de l'option --pdb sur nosetests:
tests$ nosetests test_urls_catalog.py --pdb
Dès que j'ai frappé une exception (y compris celles traitées avec élégance), pdb s'arrête là où cela se produit et je peux regarder autour de moi.
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)
Maintenant, il est clair que mon argument choices au constructeur de champ croustillant était comme c'était une liste dans une liste, plutôt qu'une liste/tuple de tuples.
'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]]
La chose intéressante est que cette pdb a lieu dans le code de crispy, pas le mien et je n'avais pas besoin de l'insérer manuellement.
Utiliser pdb
ou ipdb
. Diffrence entre ces deux est IPDB prend en charge auto complète.
Pour apb
import pdb
pdb.set_trace()
Pour ipdb
import ipdb
ipdb.set_trace()
Pour l'exécution de la nouvelle ligne hit n
clé, pour continuer hit c
clé.
Vérifiez plus d'options en utilisant help(pdb)
Pendant le développement, en ajoutant un{[2 rapide]}
assert False, value
Peut aider à diagnostiquer les problèmes dans les vues ou ailleurs, sans avoir besoin d'utiliser un débogueur.
De ma propre expérience, il y a deux voies:
-
Utilisez ipdb , qui est un débogueur amélioré qui aime pdb.
import ipdb;ipdb.set_trace()
-
Utilisez le shell django, utilisez simplement la commande ci-dessous. C'est très utile lorsque vous développez une nouvelle vue.
python manage.py shell