回顾

  • 通过前几篇文章的内容, 我们已经搭建了基于 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, content):
            resp = make_response(content)
            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 Flask, make_response, request
    from datetime import datetime, date
    
    class Page(MethodView):
        def render(self, content):
            resp = make_response(content)
            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

参考资料


FrozenMap
64 声望6 粉丝

今天,你快乐吗?