Django 漂亮的出错页面
花几分钟时间欣赏一下我们写好的Web应用程序,然后我们再来搞点小破坏。我们故意在views.py
文件中引入一项 Python 错误,注释掉 hours_ahead
视图中的offset = int(offset)
一行。
def hours_ahead(request, offset):
# try:
# offset = int(offset)
# except ValueError:
# raise Http404()
dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
return HttpResponse(html)
启动开发服务器,然后访问 /time/plus/3/
。你会看到一个包含大量信息的出错页,最上面 的一条 TypeError
信息是:"unsupported type for timedelta hours component: unicode"
.
怎么回事呢?是的,datetime.timedelta
函数要求 hours 参数必须为整型, 而我们注释掉了将 offset
转为整型的代码。 这样导致 datetime.timedelta
弹出TypeError
异常。
这个例子是为了展示 Django 的出错页面。我们来花些时间看一看这个出错页,了解一下其中 给出了哪些信息。
以下是值得注意的一些要点:
在页面顶部,你可以得到关键的异常信息: 异常数据类型、异常的参数 (如本例中的
"unsupported type"
)、在哪个文件中引发了异常、出错的行号等等。在关键异常信息下方,该页面显示了对该异常的完整 Python追踪信息。 这类似于你在Python命令行解释器中获得的追溯信息,只不过后者更具交互性。对栈中的每一帧,Django均显示了其文件名、函数或方法名、行号及该行源代码。
点击该行代码 (以深灰色显示),你可以看到出错行的前后几行,从而得知相关上下文情况。
点击栈中的任何一帧的“
Local vars
”可以看到一个所有局部变量的列表,以及在出错那一帧时它们的值。 这些调试信息相当有用。注意“
Traceback
”下面的“Switch to copy-and-paste view
”文字。 点击这些字,追溯会切换另一个视图,它让你很容易地复制和粘贴这些内容。当你想同其他人分享这些异常 追溯以获得技术支持时(比如在 Django 的IRC聊天室或邮件列表中),可以使用它。你按一下下面的“
Share this traceback on a public Web site
”按钮,它将会完成这项工作。 点击它以传回追溯信息至http://www.dpaste.com/,在那里你可以得到一个单独的URL并与其他人分享你的追溯信息。接下来的“
Request information
”部分包含了有关产生错误的Web请求的大量信息:GET和POST、cookie 值、元数据(象 CGI头)。在附录H里给出了request的对象的 完整参考。Request信息的下面,“Settings”列出了 Django 使用的具体配置信息。 (我们已经提及过
ROOT_URLCONF
,接下来我们将向你展示各式的Django设置。 附录D覆盖了所有可用的设置。)
Django 的出错页某些情况下有能力显示更多的信息,比如模板语法错误。我们讨论 Django 模板系统时再说它们。现在,取消 offset = int(offset)
这行的注释,让它重新正常工作。
不知道你是不是那种使用小心放置的 print
语句来帮助调试的程序员? 你其实可以用 Django 出错页来做这些,而不用 print
语句。 在你视图的任何位置,临时插入一个assert False
来触发出错页。 然后,你就可以看到局部变量和程序语句了。 这里有个使用hours_ahead
视图的例子:
def hours_ahead(request, offset):
try:
offset = int(offset)
except ValueError:
raise Http404()
dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
assert False
html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
return HttpResponse(html)
最后,很显然这些信息很多是敏感的,它暴露了你 Python 代码的内部结构以及Django配置,在Internet上公开这信息是很愚蠢的。不怀好意的人会尝试使用它攻击你的Web应用程序,做些下流之事。因此,Django 出错信息仅在debug
模式下才会显现。我们稍后说明如何禁用 debug
模式。 现在,你只要知道Django服务器在你开启它时默认运行在debug
模式就行了。(听起来很熟悉?页面没有发现错误,如前所述,工作正常。)
下一章
目前为止,我们已经写好了视图函数和硬编码的HTML。 在演示核心概念时,我们所作的是为了保持简单。但是在现实世界中,这差不多总是个坏主意。
幸运的是,Django内建有一个简单有强大的模板处理引擎来让你分离两种工作: 下一章,我们将学习模板引擎。
{$ activeFileHint $}