Web 開發學習筆記(5) — 抽象出 Page 類

FrozenMap發表於2019-02-16

回顧

  • 通過前幾篇文章的內容, 我們已經搭建了基於 Flask 框架的一個簡單的 Web 應用, server.py 的程式碼如下

    from flask import Flask, make_response
    from flask.views import MethodView
    app = Flask(__name__)
    
    class IndexHandler(MethodView):
        def get(self):
            resp = make_response(`It is a GET request`)
            resp.headers[`Strict-Transport-Security`] = `max-age=15768000; includeSubDomains; preload`
            return resp
    
    if __name__ == `__main__`:
        app.add_url_rule(`/`, view_func=IndexHandler.as_view(`index`))
        context = (`./server.cer`, `./server.key`)
        app.run(port=443, host=`0.0.0.0`, debug=True, threaded=True, ssl_context=context)

抽象出 Page

  • 由於我們在以後的每個頁面的 Handler 中都要用到 HSTS, 以及其他一些共用的特性, 我們將其提取出來, 抽象成一個 Page 類, 修改 server.py 如下

    from flask import Flask, make_response
    from flask.views import MethodView
    app = Flask(__name__)
    
    class Page(MethodView):
        def render(self, resp):
            resp.headers[`Strict-Transport-Security`] = `max-age=15768000; includeSubDomains; preload`
            return resp
    
    class IndexHandler(Page):
        def get(self):
            content = `It is a GET request`
            return self.render(content)
    
    if __name__ == `__main__`:
        app.add_url_rule(`/`, view_func=IndexHandler.as_view(`index`))
        context = (`./server.cer`, `./server.key`)
        app.run(port=443, host=`0.0.0.0`, debug=True, threaded=True, ssl_context=context)

提取其他共用特性

  • get_args()

    args 一般出現在 GET 請求中, 比如 Google 搜尋時位址列出現的 https://www.google.com/search?q=awesome, 其中 ? 後面的內容就是 args, 以 key-value 的形式出現. 對應剛才的例子, key 就是 q, value 就是 awesome. 如果有多組 key-value, 中間就用 & 連線, 如 ?q=awesome&type=server. 這種形式很容易讓我們聯想到 Python 的字典結構 dict. 根據 文件, Flask 是通過 ImmutableMultiDict 來儲存 args 的. 我們可以在 Page 類中增加 get_args() 方法

    from flask import request
    class Page(MethodView):
        def get_args(self, key):
            return request.args.get(key)

    這樣, 我們就可以通過呼叫 get_args() 來獲取使用者請求中的引數了, 舉個例子

    class AwesomeHandler(Page):
        def get(self):
            if self.get_args(`q`) == `awesome`:
                # do something
                return `This is an awesome page!`
  • 同樣地, 我們可以在 Page 類中增加其他特性, 如 get_date(), get_referer(), get_cookies() 等等, 編寫好的 Page 類如下

    from flask import request
    from datetime import datetime, date
    
    class Page(MethodView):
        def render(self, resp):
            resp.headers[`Strict-Transport-Security`] = `max-age=15768000; includeSubDomains; preload`
            return resp
    
        def get_args(self, key):
            return request.args.get(key)
    
        def get_date(self, year=0, month=0, day=0):
            if year and month and day:
                return date(year, month, day)
            else:
                return date.today()
    
        def get_referer(self):
            return request.headers.get(`referer`)
    
        def get_cookies(self):
            return request.cookies

參考資料

相關文章