提问人:googletorp 提问时间:7/13/2009 最后编辑:googletorp 更新时间:6/1/2021 访问量:324356
如何在 Django 中调试,好方法?[关闭]
How to debug in Django, the good way? [closed]
问:
因此,我开始学习用 Python 和后来的 Django 编写代码。第一次很难查看回溯,实际上很难弄清楚我做错了什么以及语法错误在哪里。现在已经过去了一段时间,一路走来,我想我在调试我的 Django 代码时有一个例程。由于这是在我编码经验的早期完成的,我坐下来想知道我这样做的方式是否无效并且可以更快地完成。我通常会设法找到并纠正代码中的错误,但我想知道我是否应该做得更快?
我通常只使用 Django 在启用时提供的调试信息。当事情像我想象的那样结束时,我会用语法错误破坏代码流,并查看流中那个点的变量,以确定代码在哪里做了我想要的以外的事情。
但这可以改进吗?有没有一些好的工具或更好的方法来调试你的 Django 代码?
答:
有很多方法可以做到这一点,但最直接的就是简单地 使用 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 调试器 (pdb) 用于所有类型的 Python 代码。如果您已经对 pdb 感兴趣,您还想看看使用 ipython 进行调试的 IPDB。
对 pdb 的一些更有用的扩展是
在 Django 中使用 Python 调试器,由 Seafangs 建议。
评论
manage.py runserver --pdb
manage.py test --pdb
有一些工具可以很好地配合,可以使调试任务更轻松。
最重要的是 Django 调试工具栏。
然后,您需要使用 Python 日志记录工具进行良好的日志记录。您可以将日志记录输出发送到日志文件,但更简单的选项是将日志输出发送到 firepython。要使用它,您需要使用带有 firebug 扩展的 Firefox 浏览器。Firepython 包含一个 firebug 插件,它将在 Firebug 选项卡中显示任何服务器端日志记录。
Firebug 本身对于调试您开发的任何应用程序的 Javascript 端也至关重要。(当然,假设你有一些JS代码)。
我也喜欢 django-viewtools 使用 pdb 以交互方式调试视图,但我不怎么使用它。
还有更多有用的工具,如推土机来跟踪内存泄漏(在SO的答案中也给出了其他很好的建议,用于内存跟踪)。
我在 Eclipse 中使用 pyDev 非常好,设置断点,单步执行代码,查看任何对象和变量的值,尝试一下。
评论
我真的很喜欢 Werkzeug 的交互式调试器。它类似于 Django 的调试页面,只是你在回溯的每个级别上都有一个交互式 shell。如果你使用 django-extensions,你会得到一个管理命令,该命令会启动开发服务器,并在出现异常时为你提供 Werkzeug 的调试器。runserver_plus
当然,您应该只在本地运行它,因为它赋予任何拥有浏览器的人在服务器上下文中执行任意 python 代码的权限。
评论
python 3.3
模板标签的快速提示:
@register.filter
def pdb(element):
import pdb; pdb.set_trace()
return element
现在,在模板中,您可以执行并输入一个 pdb 会话(假设您正在运行本地开发服务器),您可以在其中检查您的心满意足的内容。{{ template_var|pdb }}
element
这是查看对象到达模板时发生了什么的非常好方法。
评论
到目前为止,几乎所有内容都已经提到过,所以我只想补充一点,而不是可以使用 ipdb.set_trace(),它使用 iPython,因此功能更强大(自动完成和其他好东西)。这需要 ipdb 包,所以你只需要pdb.set_trace()
pip install ipdb
评论
我使用 PyCharm(与 eclipse 相同的 pydev 引擎)。真的帮助我直观地能够单步执行我的代码并查看正在发生的事情。
评论
我已经推到了PyPI。
这是一个简单的应用程序,这意味着您不需要每次想要闯入 pdb 时都编辑源代码。django-pdb
安装只是...
pip install django-pdb
- 添加到你的
'django_pdb'
INSTALLED_APPS
您现在可以运行: 在每个视图的开头闯入 pdb...manage.py runserver --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)
并运行:在测试失败/错误时闯入 pdb...manage.py test --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 上,当然欢迎贡献。
评论
manage.py runserver: error: unrecognized arguments: --pdb
如果使用 Aptana 进行 django 开发,请观看以下内容: http://www.youtube.com/watch?v=qQh-UQFltJQ
如果没有,请考虑使用它。
调试 python 的最简单方法(尤其是对于使用 Visual Studio 的程序员)是使用 PTVS(用于 Visual Studio 的 Python 工具)。 步骤很简单:
- 从 https://microsoft.github.io/PTVS/ 下载并安装
- 设置断点并按 F5。
- 命中断点,您可以像调试 C#/C++ 程序一样轻松地查看/更改变量。
- 这就是全部:)
如果你想使用 PTVS 调试 Django,你需要做以下事情:
- 在“项目设置 - 常规”选项卡中,将“启动文件”设置为“manage.py”,即 Django 程序的入口点。
- 在“项目设置”-“调试”选项卡中,将“脚本参数”设置为“runserver --noreload”。关键点是这里的“--noreload”。如果不设置它,则不会命中断点。
- 好好享受吧。
评论
大多数选项都提到了。 为了打印模板上下文,我为此创建了一个简单的库。 查看 https://github.com/edoburu/django-debugtools
您可以使用它来打印模板上下文,而无需任何构造:{% load %}
{% print var %} prints variable
{% print %} prints all
它使用自定义的 pprint 格式来显示标记中的变量。<pre>
我强烈推荐 epdb(扩展 Python 调试器)。
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 help 的信息。
如果要同时提供或连接到多个 epdb 实例,可以指定要侦听的端口(默认为 8080)。J.F.
import epdb; epdb.serve(4242)
>> import epdb; epdb.connect(host='192.168.3.2', port=4242)
如果未指定,host 默认为“localhost”。我把它放在这里是为了演示如何使用它来调试本地实例以外的其他东西,例如本地 LAN 上的开发服务器。显然,如果这样做,请注意设置的跟踪永远不会进入生产服务器!
快速说明一下,您仍然可以使用 epdb() 执行与已接受的答案相同的操作,但我想强调 serve 功能,因为我发现它非常有用。import epdb; epdb.set_trace()
评论
我使用 PyCharm 和不同的调试工具。还有一篇关于为新手轻松设置这些东西的好文章。你可以从这里开始。它讲述了 Django 项目的 PDB 和 GUI 调试。希望有人能从中受益。
我刚刚找到了 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 添加到 MIDDLEWARE_CLASSES,然后在请求 URL 的末尾添加 ?profile 即可激活分析器。
也可以从命令行运行pyinstrument,也可以通过导入为模块来运行pyinstrument。
评论
有时,当我想用一种特定的方法四处探索并且召唤 pdb 太麻烦时,我会补充:
import IPython; IPython.embed()
IPython.embed()
启动一个 IPython shell,该 shell 可以从调用它的位置访问局部变量。
评论
from IPython import embed
embed()
embed();exit();
pudb
debugger;
dd
我使用 PyCharm 并一直支持它。这让我付出了一点代价,但我不得不说我从中获得的好处是无价的。我尝试从控制台进行调试,我确实给了人们很多可以做到这一点的荣誉,但对我来说,能够直观地调试我的应用程序很棒。
不过我不得不说,PyCharm 确实占用了大量内存。但话又说回来,生活中没有什么好东西是免费的。他们刚刚发布了最新版本 3。它也可以很好地与 Django、Flask 和 Google AppEngine 配合使用。所以,总而言之,我想说它对任何开发人员来说都是一个非常方便的工具。
如果您还没有使用它,我建议您获得 30 天的试用版,看看 PyCharm 的强大功能。我敢肯定还有其他可用的工具,例如 Aptana。但我想我也喜欢 PyCharm 的外观。我在那里调试我的应用程序感觉很舒服。
评论
我强烈建议使用 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
正如这里其他文章中提到的 - 在你的代码中设置断点并遍历代码,看看它是否像你预期的那样运行,这是学习像 Django 这样的东西的好方法,直到你对它的行为方式有一个很好的了解——以及你的代码在做什么。
为此,我建议使用 WingIde。就像其他提到的IDE一样,漂亮且易于使用,布局漂亮,并且易于设置断点,评估/修改堆栈等。非常适合在单步执行代码时可视化代码正在执行的操作。我是它的忠实粉丝。
我还使用 PyCharm - 它具有出色的静态代码分析功能,有时可以帮助您在意识到问题存在之前发现问题。
如前所述,django-debug-toolbar 是必不可少的 - 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 项目时,非常方便。
从我的角度来看,我们可以将常见的代码调试任务分解为三种不同的使用模式:
- 有些事情引发了一个例外:runserver_plus' Werkzeug 调试器来救援。在所有跟踪级别运行自定义代码的能力是一个杀手锏。如果您完全卡住了,只需单击一下即可创建要分享的 Gist。
- 页面被渲染,但结果是错误的:再次,Werkzeug 摇滚。若要在代码中创建断点,只需键入要停止的位置即可。
assert False
- 代码工作错误,但快速查看无济于事。很可能是算法问题。叹息。然后我通常会启动一个控制台调试器 PuDB:。与 [i]pdb 相比,PuDB 的主要优势在于(当你看起来像 80 年代时)使设置自定义监视表达式变得轻而易举。使用 GUI 调试一堆嵌套循环要简单得多。
import pudb; pudb.set_trace()
啊,是的,模板的困境。对我和我的同事来说,最常见的问题是错误的上下文:要么你没有变量,要么你的变量没有某个属性。如果您使用的是调试工具栏,只需在“模板”部分检查上下文,或者,如果还不够,请在上下文填充后立即在视图代码中设置中断。
就这样吧。
评论
import pudb;pu.db
另一个建议。
您可以同时使用 nosetests 和 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 %}
现在,我知道这意味着我搞砸了表单的构造函数,我什至很清楚哪个字段有问题。但是,我可以使用 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 的代码中,而不是我的代码中,我不需要手动插入它。
use 或 .这两者的区别在于 ipdb 支持自动完成。pdb
ipdb
对于 PDB
import pdb
pdb.set_trace()
对于IPDB
import ipdb
ipdb.set_trace()
用于执行换行命中键,用于继续命中键。
使用检查更多选项n
c
help(pdb)
在开发过程中,添加快速
assert False, value
可以帮助诊断视图或其他任何地方的问题,而无需使用调试器。
我发现 Visual Studio Code 非常适合调试 Django 应用程序。标准 python launch.json 参数在附加调试器的情况下运行,因此您可以根据需要设置断点并单步执行代码。python manage.py
对于那些可能意外地将 pdb 添加到实时提交中的人,我可以建议 #Koobz 答案的扩展:
@register.filter
def pdb(element):
from django.conf import settings
if settings.DEBUG:
import pdb
pdb.set_trace()
return element
调试 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 调试器相反
- 通过代码注入闯入当前正在运行的程序(在受支持的系统上)
它具有出色的基于浏览器的用户界面。使用起来很愉快!:)
评论
在 Python 代码的相应行添加 or(格式为 python3.7)并执行它。执行将以交互式 shell 停止。在 shell 中,您可以执行 Python 代码(即打印变量)或使用以下命令:import pdb; pdb.set_trace()
breakpoint()
c
继续执行n
单步执行同一函数中的下一行s
单步执行此函数或被调用函数中的下一行q
退出调试器/执行
另请参阅:https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28
从我自己的经验来看,有两种方式:
使用 IPDB,这是一个增强的调试器,类似于 PDB。
import ipdb;ipdb.set_trace()
或(来自 python3.7)breakpoint()
使用 Django shell,只需使用下面的命令即可。当您开发新视图时,这非常有用。
python manage.py shell
评论
runserver
shell