Flask - 基本入门

简介

  • Flask 被称为微型框架,只提供了一个强健的核心,其他功能全部通过扩展库来实现;也就是说可以根据项目需要量身打造。他适合入门以及高手研究。
  • 组成:WSGI、模板引擎(Jinja2)

WEB 工作原理

  • B/S 和 C/S 架构
  • B/S 架构工作原理
    • 客户端(浏览器)<=>WEB 服务器(nginx)<=>WSGI(uWSGI)<=>Python(flask)<=> 数据路(MySQL)
    • 说明:Flask 框架自带了一个测试服务器,没有考虑性能部署。

配置虚拟环境

  • 安装虚拟环境 virtualenv

    1
    pip3 install virtualenv
    • 创建虚拟环境:virtualenv venv
    • 启动虚拟环境:source venv/bin/activate
    • 退出虚拟化境:deactivate
  • 安装 virtualenvwrapper

    • 安装 pip

      1
      sudo apt-get install python-pip
    • 安装 virtualenvwrapper

      1
      pip install virtualenvwrapper
    • 配置

      • 创建专门用于存放虚拟环境的目录:~/.virtualenvs
      • 在文件 ~/.bashrc 末尾添加如下内容:
        1
        2
        3
        4
        export WORKON_HOME=$HOME/.virtualenvs
        source $HOME/.local/bin/virtualenvwrapper.sh
        alias mkvirtualenv='mkvirtualenv -p /usr/bin/python'
        alias mkvirtualenv3='mkvirtualenv -p /usr/bin/python3'

        重新加载:source ~/.bashrc

    • 虚拟环境常用命令

      • 查看虚拟环境
        • lsvirtualenvworkon
      • 创建虚拟环境
        • Python2:mkvirtualenv 虚拟环境名
        • Python3:mkvirtualenv3 虚拟环境名
      • 使用虚拟环境
        • workon 虚拟环境名
      • 退出虚拟环境
        • deactivate
      • 切换到当前虚拟环境目录下
        • cdvirtualenv
      • 删除虚拟环境
        • rmvirtualenv 虚拟环境名
      • 创建虚拟环境 (示例)
        • mkvirtualenv3 flask

使用测试

  • 示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 导入类库
    from flask import Flask

    # 创建对象
    app = Flask(__name__)

    # 配置路由
    @app.route('/')
    def index():
    return 'Hello World'

    if __name__=='__main__':
    # 启动
    app.run()
  • 启动:python manage runserver
  • 测试:浏览器输入 127.0.0.1:5000
  • 启动参数:
    参数 说明
    debug 是否开启调试模式,默认为 False,开启后代码修改后会自动加载
    threaded 是否开启多线程模式
    port 指定端口
    host 指定主机,设置为‘0.0.0.0’可以通过 IP 访问

    app.run(debug=True, threaded=True, port=5050, host='0.0.0.0')

请求与响应

  • 变量或对象

    名称 上下文 说明
    current_app 程序上下文 当前运行的应用实例
    g 程序上下文 全局对象,处理请求的临时数据
    request 请求上下文 请求对象,包含了客户端所有的 HTTP 请求
    session 请求上下文 用户会话,用于保存需要记住的信息
  • 请求的钩子函数

    函数 说明
    before_first_request 第一次请求前
    before_request 每次请求前
    after_request 每次请求之后,前提是没有异常
    teardown_request 每次请求之后,无论是否异常

    所谓的钩子函数,就是框架给用户预留的后门

视图函数

  • 无参路由

    1
    2
    3
    @app.route('/test/')
    def test():
    return 'for test yyy'
  • 带参路由

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 带参路由,参数写在'<>'中
    @app.route('/welcome/<name>')
    def welcome(name):
    return 'Hellow %s!'%name

    # 限制参数类型
    @app.route('/user/<int:uid>')
    def user(uid):
    return '%d 号,你好!'%uid

    # path类型参数
    @app.route('/path/<path:p>')
    def path(p):
    return p

    # 多个参数处理
    @app.route('/username/<name>/uid/<uid>')
    def userinfo(name, uid):
    return name + uid
  • 说明

    • 说明:最后的 / 加上后,在测试时加不加都可以
    • 若需要参数,参数需要写在 <> 中,对应视图函数的参数要与路由参数一致
    • 若需要指定参数类型,如 int/float/path 等,应该写在参数名之前,使用 : 与参数名分隔
    • 若不指定参数类型,默认为 string ,path 其实也是字符串,只不过 / 不再是分隔符

请求 (request)

  • 客户端的所有请求信息都放在了 request 对象中
  • 常用:urlmethodargsheaders
  • 示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    # 导入类库
    from flask import Flask
    from flask import request

    # 创建对象
    app = Flask(__name__)


    # 配置路由
    @app.route('/')
    def index():
    return '<h1>Hello World</h1>'


    @app.route('/request/')
    def reg():
    # 完整的请求地址URL
    return request.url
    # 不包含get参数的请求地址
    # return request.base_url
    # 只有主机和端口
    # return request.host_url
    # 只有装饰器中的路由地址
    # return request.path
    # 请求方式
    # return request.method
    # 远程客户端地址
    # return request.remote_addr
    # 获取get参数:有同名获取第一个
    # return request.args['name']
    # return request.args.get('passwd')
    # 获取一个键对应的所有值的列表
    # print(request.args.getlist('name'))
    # 获取请求头信息
    # return request.headers['User-Agent']


    if __name__ == '__main__':
    # 启动
    app.run(debug=True, threaded=True)

响应 (response)

  • 直接返回一个字符串即可,默认状态码是 200,表示成功
  • 返回一个元组,即在字符串后直接指定状态码
  • 也可以先创建一个响应,然后返回该响应对象
  • 示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    # 导入类库
    from flask import Flask
    from flask import make_response

    # 创建对象
    app = Flask(__name__)


    # 配置路由
    @app.route('/')
    def index():
    return '<h1>Hello World</h1>'


    # 响应
    @app.route('/response/')
    def response():
    # 响应,返回一个字符串既可,默认状态码为200,表示OK
    # return 'OK'
    # 返回时可以直接指定状态码
    # return 'page not found', 404
    # 先用专门的函数构造一个响应对象,然后返回,可以指定状态码
    resp = make_response('这是通过函数构造的响应', 404)
    return resp


    if __name__ == '__main__':
    # 启动
    app.run(debug=True, threaded=True)

重定向 (redirect)

  • 说明:当网站的 URL 更换时,又需要对老地址进行支持
  • redirect重定向函数
  • url_for根据视图函数名构造路由地址,参数是视图函数名
  • 示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    # 导入类库
    from flask import Flask
    from flask import redirect
    from flask import url_for

    # 创建对象
    app = Flask(__name__)


    # 配置路由
    @app.route('/')
    def index():
    return '<h1>Hello World</h1>'


    # 带参路由,参数写在'<>'中
    @app.route('/welcome/<name>')
    def welcome(name):
    return 'Hellow %s!' % name


    @app.route('/old/')
    def old():
    # return '旧内容'
    # return redirect('/new/')
    # 根据视图函数名反向的构造路由地址
    # return url_for('new')
    # 可以构造带参的路由
    # return url_for('welcome', name='xiaoming', uid=250)
    return redirect(url_for('new'))


    @app.route('/new/')
    def new():
    return '新内容'


    if __name__ == '__main__':
    # 启动
    app.run(debug=True, threaded=True)

终止 (abort)

  • abort向系统抛出一个异常,系统会捕获并作出统一处理
  • @app.errorhandler定制错误显示
  • 示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    # 导入类库
    from flask import Flask
    from flask import abort

    # 创建对象
    app = Flask(__name__)


    # 配置路由
    @app.route('/')
    def index():
    return '<h1>Hello World</h1>'


    @app.route('/abort/')
    def err():
    # 抛出异常给系统,参数是状态码
    abort(404)
    return 'abort测试'


    # 定制404错误
    @app.errorhandler(404)
    def page_not_found(e):
    return '大哥,是不是搞错了?'


    if __name__ == '__main__':
    # 启动
    app.run(debug=True, threaded=True)

拓展

  • MVC:就是为了解耦

    • M:model,模型,即数据模型
    • V:view,视图,负责显示逻辑
    • C:controller,控制器,负责业务逻辑处理
  • MTV:功能同 MVC

    • M:model,模型,即数据模型
    • T:template,模板,负责显示逻辑
    • V:view function,视图函数,负责处理业务逻辑