1.当安装了python-dotenv时,Flask在加载环境变量的优先级是:手动设置的环境变量---.env中设置的环境变量---.flaskenv和.env中设置的环境变量。
2.pipenv install --skip-lock 跳过lock环节,最后统一使用pipenv lock
3.运行实例程序时需要将示例程序拷贝至虚拟环境同级目录下运行
4.内容概要:
- 为视图绑定多个URL
- 动态URL:在URL规则中添加变量部分,使用“<变量名>”的形式表示,Flask处理请求时会把变量名传入视图函数,如果客户端访问的URL中没有添加变量名,会返回一个404错误响应。在app.route()装饰器中可以使用default参数设置默认值。
- pipenv install watchdog --dev watchdog是一个用于监测文件变动的python库,安装后Werkzeug会自动使用它来监测文件变动。--dev只在开发环境下用到。
- Flask内置了一个简单的开发服务器(由依赖包Werkzeug提供),足够在开发和测试阶段使用。在生产环境要使用性能更好的生产服务器,以提升安全和性能。
5. 自动发现程序实例
- (pipenv run )flask run命令运行时将自动探测程序实例:
- 从当前目录寻找app.py和wsgi.py模块,并从中寻找名为app或application的程序实例。
- 从FLASK_APP环境变量(设定为程序实例所在模块的文件名)对应的值寻找名为app或application的程序实例。
6. Flask扩展
扩展即使用Flask提供的API接口编写的Python库。因为Flask扩展的编写有一些约定,所以初始化的过程大致相似,大部分扩展会提供一个扩展类,实例化这个类,并传入我们创建的程序实例app作为参数,即可完成初始化过程。扩展会在传入的程序实例上注册一些处理函数,并加载一些配置。
7. 项目配置
在Flask中配置变量就是一些大写形式的Python变量。和平时使用变量不同,这些变量都是通过Flask对象的app.config属性作为统一接口来设置和获取,它指向的Config类是字典的子类,可以像操作字典一样操作它。
- 配置的名称必须是大写的形式,小写的将不会被读取。
- 使用update()方法可以一次加载多个值:
app.config.update( SECRET_KEY="u982roihksdjlckqwpori3489ut0932o", TESTING=True )
- 除此之外,你还可以把配置变量存储在单独的Python脚本、JSON格式文件或是Python类中,config类提供了相应的方法来导入配置。
8. URL与端点
- URL规则可能被修改,使用Flask提供的url_for()函数总能获取正确的URL。
- 调用url_for函数时,第一个参数为端点(endpoint)值,端点的默认值为视图函数的名称。如果URL规则含有动态部分,需要在url_for()函数中传入相应的参数。
- url_for函数生成的URL是相对URL(即内部URL),只能在程序内部使用,若想在外部使用时,要指定_external=True。
9. Flask命令
- 除了Flask内置的命令,我们也可以自定义命令。通过创建任意一个函数,并为其添加app.cli.command()装饰器,我们就可以注册一个flask命令。
- 借助Click模块的echo函数,我们可以在命令行界面输出字符。
- 函数的文档字符串会作为提示,在flask --help时展示。
10. Flask与MVC架构
- 在MVC框架中,程序被分为三个主件:数据处理(Model)、用户界面(View)、交互逻辑(Controller)。
- 严格来说,Flask并不是MVC架构的框架,因为它没有内置的数据库模型支持。
- 如果要使用Flask来编写MVC架构的程序,视图函数可以作为控制器(Controller),视图(View)则是使用Jinjia图渲染的HTML模板,而模型可以使用其它库来实现,如Flask-SQLAlchemy。
11. 请求响应循环
- WEB服务器接收请求,通过WSGI将HTTP格式的请求数据转换成我们的Flask程序能够使用的Python数据,在程序中,Flask根据请求的URL执行对应的视图函数,获取返回值生成响应。响应一次经过WSGI转换生成HTTP响应,再经由WEB服务器传递,最终被发出请求的客户端接收。浏览器渲染响应中包含的HTML和CSS代码,并执行JS代码,最终把解析的界面呈现给用户。
- 请求报文:请求行(请求方法、URL、协议)、请求头、空行、请求体
- 响应报文:响应行(协议、状态码、原因短语)、响应头、空行、响应体
- request对象:Flask的请求对象request对象封装了客户端发来的请求报文,我们能从它获取请求报文中的所有数据。
- 请求解析和响应封装实际上大部分是由Werkzeug完成的,Flask子类化Werkzeug的Request和Response对象并添加了和程序相关的特定功能。
12. 获取URL中的查询字符串:request.args.get("", "default")
13. 查看路由匹配
- app.url_map
- flask routes
14. Flask内置的URL变量转换器
- string 不包含斜线的字符串(默认值)
- int 整形
- float 浮点数
- path 包含斜线的字符串。static路由的URL规则中的<path:filename>变量就使用了这个转换器
- any 匹配一系列给定值中的一个元素(需要在转换器后添加括号来给出可选值<any(value1, value2, ...): 变量名>)
15. 请求钩子
- before_first_request 在处理第一个请求前运行
- before_request 在处理每个请求前运行
- after_request 如果没有未处理的异常抛出,会在每个请求结束后运行
- teardown_request 即使有未处理的异常抛出,会在每个请求结束后运行
- after_this_request 会在这个请求结束后运行
16. 请求钩子的常见应用场景
- before_first_request 在玩具程序中,运行程序前我们需要进行程序的一些初始化操作,比如创建数据库表,添加管理员用户。这些操作可以放到before_first_request装饰器注册的函数中。
- before_request 比如网上要记录用户的最后在线时间,可以通过用户最后发送的请求时间来实现。为了避免在每个视图函数都添加最新在线时间的代码,我们可以仅在使用after_request钩子注册的函数中调用这段代码
- after_request 我们经常在数据库函数中进行数据库操作,比如更新、插入等,之后需要将更改提交到数据库中,提交更改的代码可以放到after_request钩子注册的函数中。
- 另一种常见的应用是建立数据库连接,通常会有多个视图函数需要建立和关闭数据库连接,这些操作基本相同,一个理想的解决方案是在请求之前(before_request)建立连接,在请求之后(teardown_request)之后关闭连接。