花幾分鐘時間欣賞一下我們寫好的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 = "In %s hour(s), it will be %s." % (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 = "In %s hour(s), it will be %s." % (offset, dt) return HttpResponse(html)
最後,很顯然這些資訊很多是敏感的,它暴露了你 Python 代碼的內部結構以及 Django 配置,在 Internet 上公開這資訊是很愚蠢的。 不懷好意的人會嘗試使用它攻擊你的 Web 應用程式,做些下流之事。 因此,Django 出錯資訊僅在 debug 模式下才會顯現。 我們稍後 說明如何禁用 debug 模式。 現在,你只要知道 Django 伺服器在你開啟它時預設運行在 debug 模式就行了。 (聽起來很熟悉? 頁面沒有發現錯誤,如前所述,工作正常。)