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