代码之家  ›  专栏  ›  技术社区  ›  googletorp

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

  •  518
  • googletorp  · 技术社区  · 15 年前

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

    我通常只使用Django在启用时提供的调试信息。当事情像我想象的那样结束时,我会用语法错误打断代码流,并查看流中那个点的变量,找出代码在哪里做了我想要做的以外的事情。

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

    27 回复  |  直到 6 年前
        1
  •  481
  •   simplyharsh    6 年前

    有很多方法可以做到,但最简单的方法是 使用 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,你也会想看看 IPDB 使用的 ipython 用于调试。

    PDB的一些更有用的扩展是

    pdb++ ,建议 Antash .

    pudb ,建议 PatDuJour .

    Using the Python debugger in Django ,建议 Seafangs .

        2
  •  219
  •   airstrike SilentGhost    12 年前

    我真的很喜欢 Werkzeug 的交互式调试器。它类似于Django的调试页面,只是在每一个回溯级别上都有一个交互式shell。如果您使用 django-extensions 你得到了 runserver_plus 管理命令启动开发服务器,并在异常情况下为您提供Werkzeug的调试器。

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

        3
  •  155
  •   Koobz    14 年前

    模板标签有点快:

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

    现在,在模板内您可以 {{ template_var|pdb }} 然后输入一个PDB会话(假设您正在运行本地devel服务器),在该会话中可以检查 element 让你心满意足。

    这是一种非常好的方法,可以在对象到达模板时看到它发生了什么。

        4
  •  80
  •   Facundo Casco    12 年前

    有一些工具可以很好地协作,并且可以使调试任务变得更容易。

    最重要的是 Django debug toolbar .

    然后您需要使用python进行良好的日志记录 logging 设施。您可以将日志输出发送到日志文件,但更简单的选项是将日志输出发送到 firepython . 要使用它,您需要将firefox浏览器与 firebug 延伸。Fireython包含一个Firebug插件,它将在Firebug选项卡中显示任何服务器端登录。

    Firebug本身对于调试您开发的任何应用程序的javascript方面也是至关重要的。(假设您当然有一些JS代码)。

    我也喜欢 django-viewtools 用于使用PDB以交互方式调试视图,但我没有那么多的用途。

    有更多有用的工具,如推土机,用于跟踪内存泄漏(这里的答案中也有其他好的建议,以便进行内存跟踪)。

        5
  •  54
  •   Tom Leys    13 年前

    我用 PyCharm (与Eclipse相同的pydev引擎)。真的有助于我在视觉上能够逐步通过我的代码,并看到正在发生的事情。

        6
  •  41
  •   d33tah    9 年前

    到目前为止,几乎所有的事情都提到了,所以我只想补充一下,而不是 pdb.set_trace() 一个人可以用 ipdb.set_trace()设置 它使用ipython,因此更强大(自动完成和其他优点)。这需要IPDB包,因此您只需要 pip install ipdb

        7
  •  32
  •   Tom Christie    13 年前

    我推过 django-pdb PyPI . 这是一个简单的应用程序,意味着您不必每次想进入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 当然,我们欢迎您的贡献。

        8
  •  20
  •   Sebastiaan M    9 年前

    调试python的最简单方法是使用ptv(用于Visual Studio的python工具),特别是对于用于Visual Studio的程序员。 步骤很简单:

    1. 从下载并安装 http://pytools.codeplex.com/
    2. 设置断点并按F5。
    3. 您的断点被命中,您可以查看/更改变量,就像调试C/C/C++程序一样简单。
    4. 就是这样:

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

    1. 在“项目设置-常规”选项卡中,将“启动文件”设置为“manage.py”,即Django程序的入口点。
    2. 在“项目设置-调试”选项卡中,将“脚本参数”设置为“runserver--noreload”。关键是这里的“-noreload”。如果不设置,则不会命中断点。
    3. 享受它。
        9
  •  15
  •   gath    15 年前

    我用 pyDev 使用Eclipse非常好,设置断点,单步执行代码,查看任何对象和变量的值,然后尝试它。

        10
  •  10
  •   Khan    11 年前

    我用 PyCharm 一路站着。这花了我一点钱,但我不得不说,我从中得到的好处是无价的。我试过从控制台进行调试,我确实给了人们很多可以做到这一点的信任,但是对于我来说,能够可视化地调试我的应用程序是非常好的。

    但我不得不说, 幻影 需要很多记忆。但同样的,生活中没有什么好东西是自由的。他们刚推出最新版本3。它还可以与Django、Flask和Google Appengine配合使用。所以,总而言之,对于任何开发人员来说,它都是一个很好的方便工具。

    如果您还没有使用它,我建议您使用试用版30天,看看Pycharm的强大功能。我确信还有其他工具可用,比如Aptana。但我想我也很喜欢小魔女的样子。我觉得在那里调试我的应用程序很舒服。

        11
  •  9
  •   Alex Morozov    9 年前

    在我看来,我们可以打破共同点 代码调试 任务分为三种不同的使用模式:

    1. 某物有 引发异常 : runserver_plus “帮助我们的是Werkzeug调试器。在所有跟踪级别运行自定义代码的能力是一个杀手。如果你完全陷入困境,只需点击一下,你就可以创建一个要点来分享。
    2. 页面已呈现,但 结果是错误的 又一次,沃克泽格岩石。要在代码中创建断点,只需键入 assert False 在你想停的地方。
    3. 代码工作错误 但是快速的眼神没有帮助。很可能是一个算法问题。叹息。然后我通常启动一个控制台调试器 PuDB : import pudb; pudb.set_trace() . 与[i]pdb相比,pudb的主要优势在于(虽然看起来你已经80多岁了)可以轻松设置自定义手表表达式。使用GUI调试一组嵌套循环要简单得多。

    啊,是的,模板的不幸。最常见的(对我和我的同事)问题是上下文错误:要么你没有变量,要么你的变量没有属性。如果你在用 debug toolbar 只需检查“模板”部分的上下文,或者,如果还不够,则在填充上下文后在视图代码中设置一个中断。

    就这样。

        12
  •  8
  •   Lie Ryan Bryan    11 年前

    有时,当我想用一种特定的方法四处探索,并且召唤PDB太麻烦时,我会补充:

    import IPython; IPython.embed()
    

    IPython.embed() 启动一个IPython shell,它可以从调用它的点访问局部变量。

        13
  •  6
  •   Jacinda    11 年前

    我强烈推荐EPDB(扩展的python调试器)。

    https://bitbucket.org/dugan/epdb

    我喜欢EPDB调试Django或其他PythonWebServer的一件事是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)
    

    如果未指定,主机默认为“localhost”。我把它放在这里演示如何使用它来调试本地实例以外的东西,比如本地LAN上的开发服务器。显然,如果这样做,请注意设置跟踪永远不会进入生产服务器!

    作为一个简短的说明,你仍然可以用EPDB做与公认答案相同的事情。( import epdb; epdb.set_trace() )但我想强调一下服务功能,因为我发现它非常有用。

        14
  •  6
  •   Hutch    10 年前

    我刚找到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中看到调用堆栈的良好图形打印输出,请签出: https://github.com/joerick/pyinstrument . 只需将pyinstrument.middleware.profilermiddleware添加到中间件类,然后添加?配置文件到激活探查器的请求URL的末尾。

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

        15
  •  3
  •   garmoncheg    11 年前

    我用 PyCharm 以及不同的调试工具。还有一篇很好的文章,关于如何为新手轻松设置这些东西。 You may start here. 它介绍了在Django项目中的PDB和GUI调试。希望有人能从中受益。

        16
  •  2
  •   user1144616    13 年前

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

    如果没有,考虑使用它。

        17
  •  2
  •   vdboor    9 年前

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

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

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

    它使用自定义的pprint格式以 <pre> 标签。

        18
  •  2
  •   Noah MacCallum    8 年前

    我发现Visual Studio代码非常适合调试Django应用程序。标准python launch.json参数运行 python manage.py 在附加了调试器之后,您可以设置断点并根据需要单步执行代码。

        19
  •  2
  •   MontyThreeCard    7 年前

    对于那些可能意外地将PDB添加到实时提交中的人,我可以建议扩展koobz答案:

    @register.filter 
    def pdb(element):
        from django.conf import settings
        if settings.DEBUG:    
            import pdb
            pdb.set_trace()
        return element
    
        20
  •  2
  •   fessacchiotto    7 年前

    调试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前端和许多其他功能,例如:

    • 源语法突出显示
    • 可视断点
    • 使用绝地完成交互式代码
    • 持久断点
    • 使用鼠标多线程/多处理支持进行深部物体检查
    • 远程调试
    • 监视表达式
    • 在调试器代码版本中
    • 流行的Web服务器集成,可在出错时中断
    • 例如,在跟踪过程中(而不是事后)异常中断,与Werkzeug调试器相反
    • 通过代码注入(在支持的系统上)插入当前运行的程序

    它有一个很棒的基于浏览器的用户界面。使用的乐趣!:)

        21
  •  2
  •   Chris    7 年前

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

    • c 继续执行
    • n 在同一函数中跳到下一行
    • s 单步执行此函数或被调用函数的下一行
    • q 退出调试器/执行

    还可以看到: https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28

        22
  •  1
  •   nitansh bareja    10 年前

    我强烈建议使用PDB。

    import pdb
    pdb.set_trace()
    

    您可以检查所有变量的值,单步执行函数等等。 https://docs.python.org/2/library/pdb.html

    用于检查所有类型的请求、响应和对数据库的命中。我使用的是Django调试工具栏。 https://github.com/django-debug-toolbar/django-debug-toolbar

        23
  •  1
  •   IanH    9 年前

    正如这里其他文章所提到的,在代码中设置断点并浏览代码以查看其行为是否如您预期的那样,这是一个很好的学习方法,比如Django,直到您对所有代码的行为以及代码正在做什么有了很好的了解。

    为此,我建议使用Wingide。和前面提到的IDES一样,它很好且易于使用,布局也很好,而且还易于设置断点、评估/修改堆栈等,非常适合在代码执行过程中可视化代码。我很喜欢它。

    另外,我还使用了pycharm——它具有出色的静态代码分析功能,可以帮助您在意识到问题存在之前发现问题。

    如前所述,Django调试工具栏是必不可少的- https://github.com/django-debug-toolbar/django-debug-toolbar

    虽然没有明确的调试或分析工具-我最喜欢的工具之一是 SQL打印中间件 可从Django Snippets获取,网址为 https://djangosnippets.org/snippets/290/

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

    我发现它对于在开发和调试应用程序时关注查询性能非常有价值。

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

    然后,如果我发现(从性能或查询数量的角度来看)发生了一些不好的事情,我将重新打开SQL语句的完整显示,以准确地看到正在发生的事情。与多个开发人员一起处理大型Django项目时非常方便。

        24
  •  0
  •   JL Peyret    8 年前

    一个额外的建议。

    你可以利用 鼻标本 PDB 一起,而不是注射 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 %}
    

    现在,我知道这意味着我在表单的构造器上加了个Google,我甚至对哪个字段有了很好的了解。但是,我能用pdb看看脆的表格在抱怨什么吗? 在模板中 ?

    是的,我能。使用 ——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参数是列表中的列表,而不是元组列表/元组。

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

    最有趣的是,这个PDB发生在Crispy的代码中,而不是我的代码,我不需要手动插入它。

        25
  •  0
  •   Abdul Gaffar    8 年前

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

    对于PDB

    import pdb
    pdb.set_trace()
    

    对于IPDB

    import ipdb
    ipdb.set_trace()
    

    用于执行新行命中 n 键,继续点击 c 关键。 通过使用检查更多选项 help(pdb)

        26
  •  0
  •   Udi    8 年前

    在开发过程中,添加一个

    assert False, value
    

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

        27
  •  0
  •   Mark White    6 年前

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

    1. 使用 ipdb ,这是一个增强的调试器,类似于PDB。

      import ipdb;ipdb.set_trace()

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

      python manage.py shell