web-dev-qa-db-ja.com

Djangoでデバッグするにはどうすればいいですか?

それで、私は Python そしてそれ以降 Django でコーディングすることを学び始めました。初めてトレースバックを調べるのが難しく、実際に私が何をしたのか、そしてどこに構文エラーがあったのかがわかりました。時間が経っていくにつれて、Djangoのコードをデバッグするためのルーチンを手に入れたと思います。これは私のコーディング経験の早い段階で行われたので、私は座って、これをどのようにして行ったのかは効果がなく、より速くできるかどうか疑問に思いました。私はたいてい自分のコードのバグを見つけて修正することができますが、もっと早くやればいいのでしょうか。

私は通常Djangoが有効にしたときに与えるデバッグ情報を使うだけです。思ったように物事が終わったら、構文エラーでコードフローを大きく分割し、フロー内のその時点での変数を調べて、コードが意図した以外のことをしているところを見つけます。

しかし、これは改善できますか? Djangoのコードをデバッグするための優れたツールやより良い方法はありますか?

539
googletorp

それを行う方法はたくさんありますが、最も簡単なのは単純に Pythonデバッガ を使うことです。 Djangoのビュー関数に次の行を追加するだけです。

import pdb; pdb.set_trace()

または

breakpoint()  #from Python3.7

そのページをブラウザにロードしようとすると、ブラウザがハングし、実際に実行されているコードでデバッグを続けるように促すプロンプトが表示されます。

しかし他の選択肢もあります(私はそれらを推奨しません)。

* return HttpResponse({variable to inspect})

* print {variable to inspect}

* raise Exception({variable to inspect})

しかし、Python Debugger(pdb)はあらゆるタイプのPythonコードに強く推奨されています。すでにpdbを使っているのであれば、 IPDB を見てください 。デバッグ用)ipython

Pdbのもっと便利な拡張は

pdb ++Antash が推奨。

pudbPatDuJour によって推奨されています。

DjangoでPythonデバッガを使うSeafangs が提案。

499
simplyharsh

私は Werkzeug のインタラクティブデバッガがとても好きです。これはDjangoのデバッグページと似ていますが、トレースバックのあらゆるレベルで対話型のシェルが表示される点が異なります。 Django-extensions を使用すると、開発サーバーを起動し、例外についてWerkzeugのデバッガを提供するrunserver_plus管理コマンドが得られます。

もちろん、これはローカルでのみ実行すべきです。ブラウザを使う人なら誰でもサーバーのコンテキストで任意のpythonコードを実行する権限を与えられるからです。

220

テンプレートタグの簡単な説明:

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

これで、テンプレートの中で{{ template_var|pdb }}を実行してpdbセッションに入り(ローカル開発サーバーを実行していると仮定した場合)、ここでelementをあなたのこころの内容に調べることができます。

オブジェクトがテンプレートに到着したときに、オブジェクトに何が起きているのかを確認するのはとても良い方法です。

157
Koobz

うまく協調し、デバッグ作業を容易にすることができるツールがいくつかあります。

最も重要なのは Djangoデバッグツールバー です。

それから、Python logging 機能を使った良いロギングが必要です。ログ出力をログファイルに送ることができますが、より簡単なオプションはログ出力を firepython に送ることです。これを使用するには、Firefoxブラウザの firebug 拡張子を使用する必要があります。 Firepythonには、Firebugタブにサーバー側のログを表示するfirebugプラグインが含まれています。

Firebug自体も、開発したすべてのアプリのJavascript側をデバッグするために重要です。 (もちろん、JSコードがいくつかあるとします)。

私はpdbを使って対話的にビューをデバッグするための Django-viewtools も好きでしたが、あまり使いません。

メモリリークを追跡するためのdozerのような便利なツールがあります(メモリ追跡のためのSOの回答にも他に良い提案があります)。

80
Van Gale

私は PyCharm (Eclipseと同じpydevエンジン)を使います。コードを一通り見て、何が起きているのかを視覚的に確認できるようにするのに本当に役立ちます。

58
PhoebeB

これまでほとんどすべてのことを述べてきたので、pdb.set_trace()の代わりに、iPythonを使用するipdb.set_trace()を使用できるため、より強力であることだけを追加します(オートコンプリートおよびその他の機能)。 。これはipdbパッケージを必要とします、従ってあなたはpip install ipdbだけを必要とします

42

私はDjango-pdbPyPI にプッシュしました。それはあなたがあなたがpdbに侵入したいと思う度にあなたのソースコードを編集する必要がないことを意味する単純なアプリです。

インストールはただです...

  1. pip install Django-pdb
  2. 'Django_pdb'INSTALLED_APPSに追加してください

すべてのビューの開始時に、manage.py runserver --pdbを実行してpdbに侵入することができます。

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)

そしてmanage.py test --pdbを実行してテストの失敗/エラーに関するpdbに侵入します。

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)

プロジェクトは GitHub でホストされ、貢献はもちろん大歓迎です。

33
Tom Christie

Pythonをデバッグする最も簡単な方法は、特にVisual Studioに慣れているプログラマーにとっては、PTVS(Visual Studio用のPythonツール)を使用することです。手順は簡単です。

  1. http://pytools.codeplex.com/ からダウンロードしてインストールしてください。
  2. ブレークポイントを設定してF5を押します。
  3. ブレークポイントに到達したら、C#/ C++プログラムをデバッグするのと同じくらい簡単に変数を表示/変更できます。
  4. それで全部です :)

PTVSを使ってDjangoをデバッグしたい場合は、次の手順を実行する必要があります。

  1. プロジェクト設定 - 一般タブで、「スタートアップファイル」をDjangoプログラムのエントリポイントである「manage.py」に設定します。
  2. 「プロジェクト設定」 - 「デバッグ」タブで、「スクリプト引数」を「runserver --noreload」に設定します。ここで重要なのは、 " - noload"です。設定しなければ、ブレークポイントは打撃を受けません。
  3. 楽しめ。
21
029xue

私はEclipseで pyDev を本当によく使っています。

16
gath

私は PyCharm を使っています。それは私に少し費用がかかりますが、私はそれから得られる利点は貴重であると言わなければなりません。私はコンソールからデバッグしようとしました、そして、私はそれをすることができる人々に多くの信用を与えますが、私のために視覚的に私のアプリケーションをデバッグすることができるのは素晴らしいです。

私は言わなければなりませんが、 PyCharm は多くのメモリを消費します。しかし、ここでもまた、人生において自由なものは何もありません。彼らはちょうど彼らの最新のバージョン3が付属していました。それはまたDjango、Flask、そしてGoogle AppEngineと非常にうまく働きます。それで、結局のところ、私はそれがすべての開発者のために持っているために素晴らしい便利なツールであると言いたいです。

まだ使っていないのであれば、PyCharmのパワーを調べるために30日間の試用版を入手することをお勧めします。他にもAptanaなどのツールがあると思います。しかし、私はPyCharmの外観も気に入っていると思います。私は自分のアプリをそこでデバッグするのがとても快適だと感じています。

11
Khan

特定の方法で探索したくてpdbを召喚するのが面倒すぎる場合は、次のように付け加えます。

import IPython; IPython.embed()

IPython.embed()は、あなたがそれを呼び出すところからローカル変数にアクセスできるIPythonシェルを起動します。

9
Lie Ryan

私の見解では、一般的なコードデバッグタスクを3つの異なる使用パターンに分類することができます。

  1. 何かが例外を発生させましたrunserver_plus 'Werkzeugデバッガを助けに。すべてのトレースレベルでカスタムコードを実行する機能は非常に重要です。そして、あなたが完全に立ち往生しているならば、あなたはクリックするだけで共有するために要旨を作成することができます。
  2. ページはレンダリングされますが、の結果が間違っています。ここでも、Werkzeugは揺れます。コードにブレークポイントを設定するには、停止したい場所にassert Falseと入力するだけです。
  3. コードは正しく機能しませんが、簡単には見えません。おそらく、アルゴリズムの問​​題です。ため息それから私は通常コンソールデバッガ PuDB を起動します:import pudb; pudb.set_trace()。 [i] pdbよりも優れている主な点は、(80年代にいるように見えても)PuDBによってカスタムのウォッチ式の設定が簡単になることです。そして、たくさんの入れ子になったループをデバッグすることはGUIを使ってはるかに簡単です。

ああ、そうです、テンプレートの問題です。 (私と私の同僚にとって)最も一般的な問題は間違った文脈です:あなたは変数を持っていないか、あなたの変数は何らかの属性を持っていません。 デバッグツールバー を使用している場合は、[テンプレート]セクションでコンテキストを確認するか、十分でない場合は表示を中断します。 'あなたのコンテキストがいっぱいになった直後のコード。

だからそうなるのです。

9
Alex Morozov

Wdb( http://www.rkblog.rk.edu.pl/w/p/debugging-python-code-browser-wdb-debugger/?goback=%2Egde_25827_member_255996401 )。それはすべての鐘と笛とかなりいいユーザーインターフェース/ GUIを持っています。作者はwdbについてこれを言います -

「PyCharmのように独自のデバッガを持つIDEがあります。それらは似たような機能を提供します。ただし、それらを使用するには、特定のIDEを使用する必要があります。あなたのニーズに合ったツールを選んでください。 "

私はそれを渡すだけだと思った。

pythonデバッガについての非常に役に立つ記事:https://zapier.com/engineering/debugging-python-boss/

最後に、DjangoであなたのコールスタックのNiceグラフィックプリントアウトを見たいのなら、チェックアウトしてください: https://github.com/joerick/pyinstrument 。 pyinstrument.middleware.ProfilerMiddlewareをMIDDLEWARE_CLASSESに追加してから、要求URLの末尾に?profileを追加してプロファイラを有効にするだけです。

コマンドラインから、またはモジュールとしてインポートしてpyinstrumentを実行することもできます。

6
Hutch

私はepdb(Extended Python Debugger)を強くお勧めします。

https://bitbucket.org/dugan/epdb

Djangoや他のPythonウェブサーバをデバッグするためにepdbについて私が好きなことの一つはepdb.serve()コマンドです。これによりトレースが設定され、接続可能なローカルポートにこれが提供されます。典型的なユースケース:

段階的に見ていきたいという意見があります。トレースを設定したいところに以下を挿入します。

import epdb; epdb.serve()

このコードが実行されると、私はPythonインタプリタを開いてサービングインスタンスに接続します。 n、sなどの標準pdbコマンドを使用して、すべての値を分析してコードをステップスルーできます。

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

そして、あなたがいつでもepdb helpとタイプすることについて学ぶことができるより多くのもの。

同時に複数のepdbインスタンスにサービスを提供または接続したい場合は、待機するポートを指定できます(デフォルトは8080)。すなわち.

import epdb; epdb.serve(4242)

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

指定しない場合、ホストのデフォルトは 'localhost'になります。ローカルLAN上の開発サーバーのように、これを使用してローカルインスタンス以外の何かをデバッグする方法を説明するために、ここに投げました。明らかに、あなたがこれをするならば、セットトレースがあなたの本番サーバーにそれを決してしないことに注意してください!

ちょっとしたメモとして、あなたはepdb(import epdb; epdb.set_trace())で受け入れられた答えと同じことをやはり行うことができますが、私はそれがとても便利であると思ったのでサーブ機能を強調したかったです。

6
Jacinda

私は PyCharm と他のデバッグツールを使います。初心者のためにそれらのものを簡単に設定することについての素晴らしい記事もあります。 ここから始めることができます。 Djangoプロジェクトでの一般的なPDBおよびGUIデバッグについて説明します。誰かがそれらから利益を得ることを願っています。

4
garmoncheg

Djangoのコードをデバッグするための最良の方法の1つはwdbを使うことです。 https://github.com/Kozea/wdb

wdbはpython 2(2.6、2.7)、python 3(3.2、3.3、3.4、3.5)およびpypyで動作します。さらに良いことには、python 3上で実行されているwdbサーバーでpython 2プログラムをデバッグすること、またはその逆のこと、あるいは他のコンピューター上で実行されているデバッグサーバーでサードパーティコンピューター上で実行されているプログラムでデバッグすることが可能です。たとえ賭け人であっても、Webインターフェースからのコードインジェクションを使って現在実行中のpythonプロセス/スレッドを一時停止することが可能になりました。 (これにはgdbとptraceが有効になっている必要があります)言い換えれば、それはあなたのブラウザで直接pdbの非常に拡張されたバージョンであり、素晴らしい機能を備えています。

サーバーをインストールして実行し、コードに次の行を追加します。

import wdb
wdb.set_trace()

著者によると、pdbに関する主な違いは次のとおりです。

プロジェクトを知らない人のために、wdbはpdbのようなpythonデバッガですが、滑らかなWebフロントエンドと多くの追加機能を備えています。

  • ソース構文の強調表示
  • 視覚的なブレークポイント
  • Jediを使ったインタラクティブなコード補完
  • 永続的なブレークポイント
  • マウスを使用した深部オブジェクト検査マルチスレッド/マルチプロセッシングサポート
  • リモートデバッグ
  • 式を見る
  • デバッガコード版
  • エラーを回避するための一般的なWebサーバーの統合
  • 例えば、werkzeugデバッガとは対照的に、トレース中(例外ではない)の例外の中断
  • コードインジェクションによる現在実行中のプログラムへの侵入(サポート対象システム上)

それは素晴らしいブラウザベースのユーザインタフェースを持っています。使うのがうれしい! :)

3
fessacchiotto

Pythonコードの対応する行にimport pdb; pdb.set_trace()を追加して実行します。実行は対話型シェルで停止します。シェルでは、Pythonコード(すなわち印刷変数)を実行することも、次のようなコマンドを使用することもできます。

  • cは実行を継続します
  • n同じ関数内の次の行に進む
  • この関数または呼び出された関数の次の行に進むs
  • qはデバッガ/実行を終了します

https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28 もご覧ください。

2
Chris

Djangoの開発にAptanaを使用している場合は、こちらをご覧ください。 http://www.youtube.com/watch?v=qQh-UQFltJQ

そうでなければ、それを使用することを検討してください。

2
user1144616

誤ってpdbをライブコミットに追加する可能性がある人のために、#Koobzという答えの拡張を提案することができます。

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

ほとんどの選択肢はすでに言及されています。テンプレートコンテキストを印刷するために、そのための簡単なライブラリを作成しました。 https://github.com/edoburu/Django-debugtools を参照してください。

{% load %}構文なしでテンプレートコンテキストを印刷するためにそれを使うことができます:

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

カスタマイズされたpprintフォーマットを使用して、変数を<pre>タグに表示します。

2
vdboor

私はVisual Studio CodeがDjangoアプリのデバッグに最適だと思います。標準のpythonのlaunch.jsonパラメータはデバッガをアタッチした状態でpython manage.pyを実行するので、ブレークポイントを設定してコードをステップスルーすることができます。

2
Noah MacCallum

私はPDBを使うことを強く勧めます。

import pdb
pdb.set_trace()

あなたはすべての変数の値を調べ、関数にステップインすることができます。 https://docs.python.org/2/library/pdb.html

データベースへのすべての種類の要求、応答およびヒットをチェックアウトするため。Django-debug-toolbar https://github.com/Django-debug-toolbar/Django-debug-を使用しています。 toolbar

1
nitansh bareja

ここで他の記事で述べたように - あなたのコードにブレークポイントを設定し、それがあなたのコードが期待通りに振る舞うかどうか確かめるためにコードを通して歩くことはあなたがそれがすべてどのように振る舞うかの良い意味がわかるまでDjangoのような何かを学ぶ素晴らしい方法です - そしてやっている。

これを行うには、WingIdeの使用をお勧めします。他の言及されたIDEと同じように、素晴らしく使いやすい、素敵なレイアウト、そしてブレークポイントを設定するのも簡単なスタックを評価/修正します。私はそれが大好きです。

また、私はPyCharmを使用しています - それは優れた静的コード分析を持ち、問題があると気づく前に問題を発見するのを助けることができます。

すでに述べたように、Django-debug-toolbarは不可欠です - https://github.com/Django-debug-toolbar/Django-debug-toolbar

そして明示的なデバッグや分析ツールではありませんが、私のお気に入りの1つは https://djangosnippets.org/snippets/から入手可能なSQL Printing Middlewareです。 290 /

これにより、ビューが生成したSQLクエリが表示されます。これにより、ORMが何をしているのか、またクエリが効率的であるか、コードを書き直す必要があるか(またはキャッシュを追加する必要があるか)がわかりやすくなります。

アプリケーションの開発とデバッグを行いながら、クエリのパフォーマンスに注目することは非常に貴重です。

もう1つのヒント - 私はSQL文ではなく要約だけを表示するために私自身の使用のためにそれをわずかに修正しました…それで私は開発とテストの間私はいつもそれを使います。また、len(connection.queries)が事前に定義されたしきい値よりも大きい場合は、追加の警告が表示されると付け加えました。

次に、(パフォーマンスやクエリ数の観点から)悪いことが起こっていることがわかった場合は、SQLステートメントをすべて表示して、何が起こっているのかを正確に確認します。複数の開発者がいる大規模なDjangoプロジェクトで作業しているときに非常に便利です。

1
IanH

開発中にクイックを追加する

assert False, value

デバッガを使用せずに、ビュー内またはその他の場所で問題を診断するのに役立ちます。

0
Udi

私自身の経験から、2つの方法があります。

  1. ipdb を使用してください。これはpdbのような拡張デバッガです。

    import ipdb;ipdb.set_trace()またはbreakpoint()(python3.7以降)

  2. 以下のコマンドを使うだけで、Django Shellを使うことができます。これは、新しいビューを開発しているときに非常に役立ちます。

    python manage.py Shell

0
Mark White

追加の提案.

ビューにpdb.set_trace()を挿入するのではなく、nosetestspdbを併用することができます。手動で。利点は、最初に起動したときに、おそらくサードパーティのコードでエラー状態を観察できることです。

これが今日の私の間違いです。

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 %}

今、私はこれが私がフォームのためのコンストラクタを間抜けしたことを意味することを知っています、そして私はどの分野が問題であるかについてさえ良い考えを持っています。しかし、pdbを使って、テンプレートの中でどのようなクリスピーなフォームが文句を言っているのかを確認できますか?

はい、できます。 nosetestsで - pdbオプションを使用する:

tests$ nosetests test_urls_catalog.py --pdb

私が何らかの例外(適切に処理されたものを含む)にぶつかるとすぐに、pdbはそれが起こる場所で止まり、私は見回すことができます。

  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)         

さて、クリスピーなフィールドコンストラクタへの私の選択の議論は、それがリスト/タプルのタプルではなく、リスト内のリストであるということであったことは明らかです。

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

きちんとしたことは、このpdbが私のものではなくcrispyのコードの中で行われているということです。私はそれを手動で挿入する必要はありませんでした。

0
JL Peyret

pdbまたはipdbを使用してください。これら2つの違いは、ipdbがオートコンプリートをサポートしていることです。

pdbの

import pdb
pdb.set_trace()

ipdb用

import ipdb
ipdb.set_trace()

改行するにはnキーを押し、続けてcキーを押します。 help(pdb)を使って他のオプションをチェックする

0
Abdul Gaffar