首页 文章

如何在Django中调试好方法? [关闭]

提问于
浏览
507

所以,我开始学习Python和后来的Django代码 . 第一次很难看回溯并实际弄清楚我做错了什么以及语法错误在哪里 . 现在已经过了一段时间,并且在某种程度上,我想我在调试我的Django代码时有一个例程 . 由于这是在我的编码经验的早期完成的,我坐下来想知道我是如何做到这一点是无效的,可以更快地完成 . 我经常设法找到并纠正我的代码中的错误,但我想知道我是否应该更快地执行它?

我通常只使用Django启用时提供的调试信息 . 当事情最终按照我的想法结束时,我会因语法错误而破坏代码流,并查看流程中该点的变量以找出代码,其中代码执行的操作不是我想要的 .

但这可以改善吗?是否有一些好的工具或更好的方法来调试Django代码?

27 回答

  • 10

    调试python的最简单方法 - 特别是对于习惯于Visual Studio的程序员 - 使用的是PTVS(Visual Studio的Python工具) . 步骤很简单:

    • http://pytools.codeplex.com/下载并安装

    • 设置断点并按F5 .

    • 您的断点被点击,您可以像调试C#/ C程序一样轻松查看/更改变量 .

    • 这就是全部:)

    如果要使用PTVS调试Django,则需要执行以下操作:

    • 在项目设置 - 常规选项卡中,将"Startup File"设置为"manage.py",这是Django程序的入口点 .

    • 在项目设置 - 调试选项卡中,将"Script Arguments"设置为"runserver --noreload" . 关键点在于"--noreload" . 如果你不被击中 .

    • 享受吧 .

  • 40

    快速模板标签:

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

    现在,在模板中,您可以执行 {{ template_var|pdb }} 并输入一个pdb会话(假设您正在运行本地开发服务器),您可以在其中检查 element 到您心脏的内容 .

    这是一种非常好的方式来查看对象到达模板时发生了什么 .

  • 51

    我使用PyCharm和不同的调试工具 . 还有一个很好的文章设置为新手轻松设置这些东西 . You may start here.它讲述了一般用于Django项目的PDB和GUI调试 . 希望有人能从中受益 .

  • 2

    调试Django代码的最佳选择之一是通过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调试器相反例如通过代码打破当前正在运行的程序注射(在支持的系统上)

    它有一个很棒的基于浏览器的用户界面 . 使用愉快! :)

  • 1

    大多数选项都是提到的 . 为了打印模板上下文,我为此创建了一个简单的库 . 见https://github.com/edoburu/django-debugtools

    您可以使用它来打印模板上下文,而不需要任何 {% load %} 构造:

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

    它使用自定义的pprint格式在 <pre> 标记中显示变量 .

  • 19

    另外一个建议 .

    您可以一起利用 nosetestspdb ,而不是手动在视图中注入 pdb.set_trace() . 优点是您可以在第一次启动时观察错误情况,可能是第三方代码 .

    今天对我来说这是一个错误 .

    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来查看哪些脆弱形式正在抱怨, within a template

    我可以 . 在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)
    

    现在,很明显我对crispy字段构造函数的选择参数是列表中的列表,而不是元组的列表/元组 .

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

    巧妙的是,这个pdb是在crispy的代码中发生的,而不是我和我的代码不需要手动插入 .

  • 0

    我刚刚找到了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(其中一些是非自由的,或者可能并非全部可用)平台) . 根据您的需求选择合适的工具 . “

    以为我只是传递它 .

    Also a very helpful article about python debuggers: https://zapier.com/engineering/debugging-python-boss/

    Finally ,如果您想在Django中看到调用堆栈的精美图形打印输出,请结帐:https://github.com/joerick/pyinstrument . 只需将pyinstrument.middleware.ProfilerMiddleware添加到MIDDLEWARE_CLASSES,然后将?profile添加到请求URL的末尾以激活探查器 .

    也可以从命令行运行pyinstrument或作为模块导入 .

  • 2

    在开发过程中,快速添加

    assert False, value
    

    可以帮助诊断视图或其他任何地方的问题,而无需使用调试器 .

  • 0

    使用 pdbipdb . 这两者之间的差异是ipdb支持自动完成 .

    对于pdb

    import pdb
    pdb.set_trace()
    

    对于ipdb

    import ipdb
    ipdb.set_trace()
    

    对于执行新行命中 n 键,继续按 c 键 . 使用 help(pdb) 查看更多选项

  • 1

    从我的角度来看,我们可以将常见的代码调试任务分解为三种不同的使用模式:

    • 有什么东西 raised an exceptionrunserver_plus ' Werkzeug debugger to the rescue. The ability to run custom code at all the trace levels is a killer. And if you'完全卡住了,只需点击一下就可以创建一个Gist来分享 .

    • 页面被渲染,但 result is wrong :再次,Werkzeug摇滚 . 要在代码中创建断点,只需在要停止的位置键入 assert False .

    • Code works wrong ,但快速看起来没有帮助 . 最有可能的是算法问题 . 叹 . 然后我通常会启动一个控制台调试器PuDBimport pudb; pudb.set_trace() . 与[i] pdb相比的主要优点是PuDB(看起来像你're in 80')使得设置自定义监视表达式变得轻而易举 . 使用GUI,调试一堆嵌套循环要简单得多 .

    啊,是的,模板' woes. The most common (to me and my colleagues) problem is a wrong context: either you don' t有一个变量,或者你的变量没有't have some attribute. If you'使用debug toolbar,只需检查"Templates"部分的上下文,或者,如果在你的上下文填满之后它是's not sufficient, set a break in your views'代码 .

    就这样吧 .

  • 79

    到目前为止几乎所有内容都已被提及,所以我只会添加 pdb.set_trace() 而不是 pdb.set_trace() 可以使用 ipdb.set_trace() 使用iPython,因此更强大(自动完成和其他好东西) . 这需要ipdb包,所以你只需要 pip install ipdb

  • 6

    根据我自己的经验,有两种方式:

    • 使用ipdb,这是一个增强的调试器,喜欢pdb .

    import ipdb;ipdb.set_trace()

    • 使用django shell,只需使用下面的命令 . 在开发新视图时,这非常有用 .

    python manage.py shell

  • 154

    在Python代码的相应行添加 import pdb; pdb.set_trace() 并执行它 . 执行将以交互式shell停止 . 在shell中,您可以执行Python代码(即打印变量)或使用如下命令:

    • c 继续执行

    • n 步进到同一函数中的下一行

    • s 步进此函数或调用函数的下一行

    • q 退出调试器/执行

    另见:https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28

  • 9

    有时当我想在一个特定的方法中探索并召唤pdb太麻烦时,我会补充:

    import IPython; IPython.embed()
    

    IPython.embed() 启动一个IPython shell,它可以从您调用它的位置访问本地变量 .

  • 15

    如果使用Aptana进行django开发,请观看:http://www.youtube.com/watch?v=qQh-UQFltJQ

    如果没有,请考虑使用它 .

  • 6

    我发现Visual Studio Code对于调试Django应用程序非常棒 . 标准的python launch.json参数在附加调试器的情况下运行 python manage.py ,因此您可以根据需要设置断点并逐步执行代码 .

  • 8

    正如在这里的其他帖子中所提到的 - 在代码中设置断点并遍历代码以查看它是否像您期望的那样行为是一种很好的方式来学习像Django之类的东西,直到您很好地理解它的行为方式 - 以及您的代码是在做 .

    为此,我建议使用WingIde . 就像其他提到的IDE一样好用且易于使用,漂亮的布局以及易于设置的断点评估/修改堆栈等 . 完美可视化您的代码在您逐步完成时所做的工作 . 我是它的忠实粉丝 .

    我也使用PyCharm - 它具有出色的静态代码分析,有时可以帮助发现问题,然后才意识到它们存在 .

    如前所述,django-debug-toolbar是必不可少的 - https://github.com/django-debug-toolbar/django-debug-toolbar

    虽然没有明确的调试或分析工具 - 我最喜欢的一个是 SQL Printing Middleware ,可从Django Snippets获得https://djangosnippets.org/snippets/290/

    这将显示视图生成的SQL查询 . 这将使您很好地了解ORM正在做什么以及您的查询是否有效或者您需要重新编写代码(或添加缓存) .

    我发现在开发和调试我的应用程序时,密切关注查询性能是非常宝贵的 .

    只是另外一个提示 - 我稍微修改它以供我自己使用,只显示摘要而不是SQL语句....所以我总是在开发和测试时使用它 . 我还补充说,如果len(connection.queries)大于预定义的阈值显示一个额外的警告 .

    然后,如果我发现一些不好的东西(从性能或查询数量的角度来看)正在发生,我会转回SQL语句的完整显示,以确切了解发生了什么 . 当您与多个开发人员一起开展大型Django项目时,非常方便 .

  • 0

    我使用PyCharm并一直支持它 . 它花了我一点但我不得不说我摆脱它的优势是无价的 . 我尝试从控制台调试,我确实给了很多人可以做到这一点的功劳,但对我来说,能够直观地调试我的应用程序是很棒的 .

    我不得不说,PyCharm确实占用了很多内存 . 但话说回来,生活中没有任何好处是免费的 . 他们刚刚推出了最新版本3.它还与Django,Flask和Google AppEngine配合得很好 . 总而言之,对于任何开发人员来说,我都是一个非常方便的工具 .

    如果您还没有使用它,我建议您试用30天的试用版来了解PyCharm的强大功能 . 我确信还有其他工具可供选择,例如Aptana . 但我想我也喜欢PyCharm的样子 . 我觉得在那里调试我的应用程序很舒服 .

  • 2

    我使用PyCharm(与eclipse相同的pydev引擎) . 真的帮助我在视觉上能够逐步完成我的代码,看看发生了什么 .

  • 214

    我使用pyDev与Eclipse非常好,设置断点,步入代码,查看任何对象和变量的值,尝试一下 .

  • 0

    我真的很喜欢Werkzeug 's interactive debugger. It',类似于Django的调试页面,除了你在每个级别的回溯上获得一个交互式shell . 如果使用django-extensions,则会得到 runserver_plus 管理命令,该命令启动开发服务器并为异常提供Werkzeug的调试器 .

    当然,您应该只在本地运行它,因为它为任何拥有浏览器的人提供了在服务器上下文中执行任意python代码的权限 .

  • 31

    有很多方法可以做到,但最直接的是简单地使用Python debugger . 只需将以下行添加到Django视图函数中:

    import pdb; pdb.set_trace()
    

    如果您尝试在浏览器中加载该页面,浏览器将挂起并提示您对实际执行的代码进行调试 .

    但是还有其他选择(我不推荐它们):

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

    但是,对于所有类型的Python代码,强烈建议使用Python调试器(pdb) . 如果您已经进入pdb,那么您还需要查看使用ipython进行调试的IPDB .

    对pdb有一些更有用的扩展

    pdb++,由Antash建议 .

    pudb,由PatDuJour建议 .

    Using the Python debugger in Django,由Seafangs建议 .

  • 470

    我强烈建议使用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

  • 2

    我把 django-pdb 推到PyPI . 每次想要破解pdb时,都需要编辑源代码 .

    安装只是......

    • pip install django-pdb

    • '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,当然欢迎捐款 .

  • 2

    我强烈推荐epdb(Extended Python Debugger) .

    https://bitbucket.org/dugan/epdb

    我喜欢epdb用于调试Django或其他Python Web服务器的一件事是epdb.serve()命令 . 这将设置跟踪并在您可以连接的本地端口上提供此跟踪 . 典型用例:

    我认为我想逐步完成 . 我将在我想要设置跟踪的位置插入以下内容 .

    import epdb; epdb.serve()
    

    执行此代码后,我打开Python解释器并连接到服务实例 . 我可以使用标准的pdb命令(如n,s等)分析所有值并逐步执行代码 .

    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帮助的更多信息 .

    如果要同时提供或连接到多个epdb实例,可以指定要侦听的端口(默认为8080) . 即

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

    如果未指定,则host默认为“localhost” . 我把它扔到这里来演示如何使用它来调试除本地实例之外的其他东西,比如本地LAN上的开发服务器 . 显然,如果你这样做,请注意设置的跟踪永远不会进入你的 生产环境 服务器!

    作为一个快速说明,您仍然可以使用epdb( import epdb; epdb.set_trace() )执行与接受的答案相同的操作,但我想强调服务功能,因为我发现它非常有用 .

  • 2

    对于那些可能意外地将pdb添加到实时提交中的人,我可以建议#Koobz的这个扩展回答:

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

    有一些工具可以很好地协作,可以使您的调试任务更容易 .

    最重要的是Django debug toolbar .

    然后,您需要使用Python logging工具进行良好的日志记录 . 您可以将日志记录输出发送到日志文件,但更简单的选择是将日志输出发送到firepython . 要使用此功能,您需要使用扩展名为firebug的Firefox浏览器 . Firepython包含一个firebug插件,可以在Firebug选项卡中显示任何服务器端日志记录 .

    Firebug本身对于调试您开发的任何应用程序的Javascript方面也很关键 . (假设你当然有一些JS代码) .

    我也喜欢django-viewtools用于使用pdb以交互方式调试视图,但我没有那么多使用它 .

    有更多有用的工具,如推土机,用于追踪内存泄漏(在SO的内存跟踪答案中也有其他好的建议) .

相关问题