1. 程式人生 > >3.3 自定義錯誤頁面

3.3 自定義錯誤頁面

如果你在瀏覽器的位址列中輸入了無效的路由,會看到一個狀態碼為 404 的錯誤頁面。與 使用 Bootstrap 的頁面相比,現在這個錯誤頁面太簡陋、平庸,而且與現有頁面不一致。

像常規路由一樣,Flask 允許應用使用模板自定義錯誤頁面。最常見的錯誤程式碼有兩個: 404,客戶端請求未知頁面或路由時顯示;500,應用有未處理的異常時顯示。示例 3-6 使 用 app.errorhandler 裝飾器為這兩個錯誤提供自定義的處理函式。

示例 3-6 hello.py:自定義錯誤頁面

@app.errorhandler(404) 
def page_not_found(e): 
    return render_template('404.html'), 404

@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500

與檢視函式一樣,錯誤處理函式也返回一個響應。此外,錯誤處理函式還要返回與錯誤對 應的數字狀態碼。狀態碼可以直接通過第二個返回值指定。

錯誤處理函式中引用的模板也需要我們編寫。這些模板應該和常規頁面使用相同的佈局, 因此要有一個導航欄和顯示錯誤訊息的頁頭。

編寫這些模板最直接的方法是複製 templates/user.html,分別建立 templates/404.html 和 templates/500.html,然後把這兩個檔案中的頁頭元素改為相應的錯誤訊息。但是這麼做會 帶來很多重複勞動。

Jinja2 的模板繼承機制可以幫助我們解決這一問題。Flask-Bootstrap 提供了一個具有頁面基 本佈局的基模板,同樣,應用也可以定義一個具有統一頁面佈局的基模板,其中包含導航 欄,而頁面內容則留給衍生模板定義。

示例 3-7 展示了 templates/base.html 的內容,這是一 個繼承自 bootstrap/base.html 的新模板,其中定義了導航欄。這個模板本身也可作為其他模 板的二級基模板,例如 templates/user.html、templates/404.html 和 templates/500.html。

示例 3-7 templates/base.html:包含導航欄的應用基模板

{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation"> 
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" 
             data-toggle="collapse" data-target=".navbar-collapse"> 
                <span class="sr-only">Toggle navigation</span> 
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Flasky</a> 
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Home</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    {% block page_content %}{% endblock %} 
</div>
{% endblock %}

這個模板中的 content 區塊裡只有一個 <div> 容器,其中包含一個新的空區塊,名為 page_ content,區塊中的內容由衍生模板定義。

現在,應用中的模板繼承自這個模板,而不直接繼承自 Flask-Bootstrap 的基模板。通過繼 承 templates/base.html 模板編寫自定義的 404 錯誤頁面就簡單了,如示例 3-8 所示。500 錯 誤頁面的編寫方式與此類似

示例 3-8 templates/404.html:使用模板繼承機制自定義 404 錯誤頁面

{% extends "base.html" %}

{% block title %}Flasky - Page Not Found{% endblock %}

{% block page_content %} 
<div class="page-header"> 
    <h1>Not Found</h1> 
</div>
{% endblock %}

錯誤頁面在瀏覽器中的顯示效果如圖 3-2 所示。

圖 3-2:自定義的 404 錯誤頁面

templates/user.html 模板也可以通過繼承這個基模板來簡化內容,如示例 3-9 所示。

示例 3-9 templates/user.html:使用模板繼承機制簡化頁面模板

{% extends "base.html" %}

{% block title %}Flasky{% endblock %}

{% block page_content %}
<div class="page-header"> 
    <h1>Hello, {{ name }}!</h1> 
</div>
{% endblock %}

《基於Python的Web應用開發實戰(第二版)》