【鱼书】1. Flask 的基本原理与核心知识

1 鱼书是一个什么样的产品

一句话概括:将自己不要的书,免费赠送给他人。

(如果不能一句话概括,说明定位不清晰)

2 开发环境

使用 pipenv 来取代 virtualenv。

2.1 安装 python 环境

安装python3:brew install python

2.2 检验 python 和 pip 是否安装好

➜ ~ python3 -V
Python 3.6.5
➜ ~ pip3 -V
pip 9.0.3 from /usr/local/lib/python3.6/site-packages (python 3.6)

2.3 用 pipenv 创建虚拟环境

mkdir fisher
cd fisher
pip3 install pipenv
pipenv install  // 创建虚拟环境
pipenv shell  // 进入虚拟环境
pipenv install flask  // 安装 flask
exit  // 退出虚拟环境
pipenv shell  // 再次进入虚拟环境
pipenv graph  // 查看安装包的关系

2.4 开发工具

  • Pycharm,要支持断点调试,自动重启服务器
  • Xampp(MySQL),我习惯使用 MAMP(Windows 下使用 WAMP)
  • Navicat(数据库可视化管理工具)

2.5 Pycharm切换虚拟环境

3 Flask 最小原型与唯一 URL 原则

3.1 最小原型

"""
 Created by plough on 2018/4/18.
"""
from flask import Flask


app = Flask(__name__)


@app.route('/hello/')
def hello():
    return 'Hello, plough'


app.run()

视图函数,即 MVC 中的 Controller。

运行之后,访问 http://127.0.0.1:5000/hello 可看到结果。

3.2 重定向

如果路由是 @app.route('/hello'),访问 http://127.0.0.1:5000/hello/ 没有结果。
反之,访问 http://127.0.0.1:5000/hello 时,会重定向为 http://127.0.0.1:5000/hello/。
可用浏览器监控网络请求查看具体情况。

3.3 唯一URL

与 seo 有关

4 调试模式

app.run(debug=True)

作用:

  • 有改动后自动重启服务器
  • 在网页中显示异常

5 路由的另一种注册方法

如果不使用装饰器注册路由,可以直接调用 add_url_rule(不推荐这种方式)

# @app.route('/hello/')
def hello():
    return 'Hello, plough'


app.add_url_rule('/hello', view_func=hello)

实际上,装饰器内部也是使用了这个函数。
app.route 的源码:

6 app.run 相关参数与 flask 配置文件

6.1 app.run 相关参数

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

配置 host='0.0.0.0' 后,可以外网访问服务器。port 指定端口号。

6.2 配置文件

在正式环境下,不能开启 debug 模式。怎么办?可以在部署时,修改为 debug=False。但是这样做违反了一个原则:生产环境和部署环境的源代码一定要是镜像关系(两份源代码一模一样)。

我们使用配置文件来解决。

在 fisher.py 同级新建一个配置文件 config.py,内容如下(所有配置参数必须大写):

DEBUG = True

fisher.py 中使用这个配置文件,核心代码如下:

app.config.from_object('config')
app.run(host='0.0.0.0', debug=app.config['DEBUG'], port=8081)

7 if __name__ 的作用

加上 if __name__ == '__main__' 之后,下面的代码只会在当前文件作为入口文件时执行。但是,这又有什么意义呢?生产环境下,我们不使用 flask 自带的服务器,fisher.py 会作为一个模块被服务器加载。如果不加 ifmain,就会在模块加载的同时,启动 flask 自带服务器。

if __name__ == '__main__':
    # 生产环境 nginx+uwsgi 下,以下代码不会执行
    app.run(host='0.0.0.0', debug=app.config['DEBUG'], port=8081)

8 响应对象:Response

视图函数最终返回的实际是一个 Response 对象,所以可以设置 HTTP 响应头部信息。

例1:返回纯文本

@app.route('/hello/')
def hello():
    headers = {
        'content-type': 'text/plain'
    }
    response = make_response('<html></html>')
    response.headers = headers
    return response

例2:跳转页面

@app.route('/hello/')
def hello():
    headers = {
        'content-type': 'text/plain',
        'location': 'http://www.bing.com'
    }
    response = make_response('<html></html>', 301)
    response.headers = headers
    return response

例3:返回 json

@app.route('/hello/')
def hello():
    headers = {
        'content-type': 'application/json'
    }
    response = make_response('{status: success}')
    response.headers = headers
    return response

response 还能设置 cookie 等内容,略。

简写方式:

@app.route('/hello/')
def hello():
    headers = {
        'content-type': 'application/json'
    }
    return '{status: success}', 200, headers