学习目标
-
了解Flask框架,能够说出Flask框架的发展史以及特点
-
熟悉隔离Python环境的创建方式,能够独立在计算机上创建隔离的Python环境
-
掌握Flask的安装方式,能够独立在计算机上安装Flask框架
-
掌握PyCharm配置隔离环境的方式,能够独立在PyCharm工具中配置隔离环境
-
掌握Flask程序的基本结构,能够归纳Flask类、路由、视图函数和开发服务器的作用
-
熟悉配置项,能够列举至少5个Flask配置项的作用
-
掌握配置信息的使用,能够通过访问字典元素、导入文件和导入对象这3种方式
-
熟悉Flask扩展包,能够列举至少3个Flask扩展包的用途
Web应用程序发展至今涵盖的技术持续扩大,这在一定程度上给Web应用程序的开发者增加了开发难度。为了提高开发者编写Web应用程序的效率,Python引入了一些成熟的Web应用程序框架,开发者只需要按照框架的约定,在指定位置编写核心业务的逻辑代码即可。 Flask作为目前比较流行的Web应用程序框架,自发布以来备受好评,在Web开发领域占据一席之地。本章将围绕着Flask框架的入门知识进行讲解,使读者对Flask框架建立初步的认识。
1.1 Flask简介
Flask是一个用Python编写的微框架,它可以帮助开发者在短时间内完成一个功能丰富的Web应用程序。微框架并不意味着将Web应用程序的所有代码放置在一个py文件中,而是意味着代码简洁且易于扩展。 Flask默认依赖两个外部库:Werkzeug WSGI工具包和Jinja2模板引擎,它只保留了Web开发的核心功能,而不包括用户认证、表单验证、发送邮件等其他Web应用程序框架通常包含的功能。开发者若需要给Flask程序添加额外的功能,可以在Flask官网找到相应的扩展包进行开发。
Flask之所以如此受欢迎,离不开其自身具备的几个特点。
1.内置开发服务器和调试器
Flask自带开发服务器,它可以让开发者在调试Web应用程序时无须安装其他的网络服务器,比如Tomcat、JBoss、Apache等,为程序正式投入运行提供了一定的保障。另外,基于Flask开发的程序默认处于调试状态,当程序运行出现异常时,Flask程序会同时向启动Python程序的控制台和HTTP客户端发送错误信息。
2.使用Jinja2模板
Flask使用Jinja2模板引擎将HTML页面与应用程序联系起来。Jinja2是一个灵活的模板引擎技术,它由Django模板引擎发展而来,但比Django模板引擎更加高效。Jinja2模板引擎使用配制的语义系统,它不仅提供了灵活的模板继承技术,还可以自动防止XSS跨站攻击。
3.极强的定制型
Flask社区提供了功能丰富的扩展包,让程序在保持核心功能简单的同时实现功能的丰富与扩展。开发者可以根据自己的需求添加扩展包,也可以自行开发扩展包,借助扩展包来快速开发一个功能丰富的网站,并实现对网站的个性化定制。
4.基于Unicode编码
Flask完全基于Unicode编码格式,这对制作非纯ASCII字符集的网站而言非常方便。由于HTTP协议支持传输任何编码格式,但该协议要求每次传输时要在请求头中显式指定使用的编码格式,Flask程序默认会为请求头指定UTF-8编码,使开发者无须再担心编码问题。
5.完全兼容WSGI 1.0标准
WSGI(Web服务器网关接口)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口,它制定了一套通信标准,保证Web服务器可以跟Web应用程序之间相互通信。Flask程序完全兼容WSGI,它能够运行到任何Web服务器。
6.无缝衔接单元测试
Flask提供了一个与Python自带的单元测试框架unittest无缝衔接的测试接口,即Flask对象的test_client()函数,通过该函数测试程序可以模拟HTTP访问客户端,调用Flask路由绑定的视图函数,并且获取视图函数的返回值进行自定义的验证。
1.2 搭建Flask开发环境
1.2.1 创建虚拟的Python环境
在实际开发Flask程序时,程序的不同版本可能会依赖不同的环境,这时需要在系统中安装多个版本的Python解释器或依赖包,如果直接在物理环境中进行配置,那么多个版本的Python解释器之间可能会产生干扰。为了解决这个问题,我们需要使用virtualenv工具创建虚拟环境,以隔离不同版本的Python解释器。
在使用virtualenv工具之前,我们需要先在计算机中安装virtualenv工具。virtualenv工具可通过pip命令在线安装,具体命令如下所示。
pip install virtualenv
一台计算机中可以创建多个虚拟环境,我们可以将不同版本的Python解释器安装到不同的虚拟环境中。
1.创建虚拟环境
创建虚拟环境的命令格式如下所示。
virtualenv 虚拟环境名
virtualenv –p Python解释器的路径 虚拟环境名
若通过第1个命令创建虚拟环境,则虚拟环境中使用的Python版本是由系统环境变量设置的Python解释器决定的;若通过第2个命令创建虚拟环境,则虚拟环境中使用的Python版本是由用户显式指定的Python解释器决定的。
例如,在E:\env_space目录下通过第1个命令创建虚拟环境flask_env,具体命令如下所示。
E:\env_space>virtualenv flask_env
2.使用虚拟环境
若希望使用虚拟环境,需要执行虚拟环境目录Scripts下的activate文件。例如,使用刚刚创建的虚拟环境flask_env,具体命令如下所示。
E:\env_space>.\flask_env\Scripts\activate
上述命令执行后,会工作在虚拟环境flask_env下,并在提示符前面显示虚拟环境的名称flask_env,具体如下所示。
(flask_env) E:\env_space>
3.退出虚拟环境
使用deactivate命令可以退出当前工作的虚拟环境。例如,使用deactivate命令退出虚拟环境flask_env,具体命令如下所示。
(flask_env) E:\env_space>deactivate
E:\env_space>
多学一招:requirement.txt
不同的Flask项目可能会依赖不同的虚拟环境,若要在新计算机中运行项目,就需要重复为该项目配置一套相同的虚拟环境,为了区分和记录每个项目的依赖包及其版本,以便在新计算机中复现项目的虚拟环境,我们可以通过一个requirement.txt文件记录项目的所有依赖包及其版本号,以便在新计算机中实现一键安装的效果。 需要说明的是,requirement.txt文件的名称是开发者之间约定俗成的,也可以进行重新命名。
requirement.txt文件的使用一般分为以下两步。
(1)通过pip命令将虚拟环境依赖的扩展包及其版本号记录到requirement.txt文件中,具体命令如下所示。
pip freeze > requirements.txt
(2)在新计算机中,通过pip命令根据requirement.txt文件记录的依赖包及其版本号安装相应版本的依赖包,具体命令如下所示。
pip install -r requirements.txt
1.2.2 安装Flask
若我们要开发Flask项目,还需要在虚拟环境中安装Flask。Flask是由Python编写的框架,也可以直接通过pip命令进行安装。例如,在虚拟环境flask_env中使用pip命令安装Flask 2.0.2,具体命令如下所示。
(flask_env) E:\env_space>pip install flask
Flask安装了6个依赖包,分别是Jinja2、MarkupSafe、Werkzeug、click、colorama和itsdangerous。
依赖包 | 版本 | 说明 |
---|---|---|
Jinja2 | 3.0.2 | 模板渲染引擎 |
MarkupSafe | 2.0.1 | HTML字符转义工具 |
Werkzeug | 2.0.2 | WSGI工具集,它封装了Web框架中的很多内容,包含请求、响应、WSGI开发服务器、调试器和重载器 |
click | 8.0.1 | 命令行工具 |
colorama | 0.4.4 | 命令行彩色显示工具 |
itsdangerous | 2.0.1 | 提供各种加密签名功能 |
为了验证Flask包是否安装成功,我们可以在命令行窗口中输入"python"进入Python解释器,并在Python解释器中尝试导入Flask,具体如下所示。
python
(flask_env) E:\env_space>python
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import flask
执行导入flask库的指令后,没有产生任何的错误信息,说明安装成功了。
1.2.3 安装PyCharm
PyCharm是一款较多开发者使用的集成开发环境,它具有调试、语法高亮、Project管理、代码跳转、智能提示、单元测试、版本控制等功能,可以实现程序编写、运行、测试一体化。
打开浏览器,访问PyCharm官网的下载页面。
Professional是专业版本,该版本支持Django、Flask、远程开发、数据库和SQL语句等更多的高级功能,且需要用户付费购买。 Community是社区版本,该版本属于轻量级的Python开发工具,且是免费的。
该安装步骤过程在python程序设计课程中已经介绍过了,这里不再赘述。
1.2.4 在PyCharm中配置虚拟环境
若要使用PyCharm工具开发Flask程序,既可以另行创建新的虚拟环境,也可以使用创建好的虚拟环境进行开发。接下来,在PyCharm工具中新建一个项目,并为该项目配置虚拟环境flask_env。
首次打开PyCharm工具时会进入Welcome to PyCharm界面。
单击Welcome to PyCharm界面中的"Create New Project"按钮进入New Project界面。
Location文本框用于填写项目的路径及名称,默认名称为untitled; Project Interpreter用于选择Python解释器,它包含New environment using和Existing interpreter两个选项,其中New environment using代表新创建的环境,Existing interpreter代表已经存在的Python解释器。
将项目的名称由untitled修改为first_pro,单击标注的 按钮弹出Add Python Interpreter窗口。
Virtualenv Environment表示添加虚拟环境中的Python解释器,Conda Environment表示添加Conda环境中的Python解释器,System Interpreter表示添加本地的Python解释器。
单击Add Python Interpreter窗口中标注的 按钮,弹出Select Python Interpreter窗口,在该窗口中选择虚拟环境flask_env中的python.exe。
单击Select Python Interpreter窗口中的"OK"按钮,关闭Select Python Interpreter窗口,跳转回Add Python Interpreter窗口,在Add Python Interpreter窗口中单击"OK"按钮,关闭Add Python Interpreter窗口并跳转回New Project界面,此时New Project界面中显示了选择的Python解释器。
单击New Project界面中的"Create"按钮,进入first_pro项目的主界面。
1.3 开发第一个Flask程序
1.3.1 编写Hello Flask程序
在first_pro项目中创建一个名称app的py文件,并在该文件中编写Hello Flask程序的代码,具体代码如下所示。
python
# 导入Flask类
from flask import Flask
#实例化Flask类
app=Flask(__name__)
# 定义视图函数,并为该函数注册路由
@app.route("/")
def hello_flask():
return "<p>Hello,Flask!</p>"
if __name__ == "__main__":
# 启动开发服务器
app.run()
在浏览器的地址栏中输入http://127.0.0.1:5000/,按下回车键后看到的页面效果如下图所示。
1.3.2 程序的基本结构
Hello Flask程序包含3个比较重要的部分,分别是Flask类、开发服务器、路由与视图。
1.Flask类
Flask类是flask包中的核心类,该类中封装了很多与Flask程序相关的方法,通过这些方法可以轻松地对Flask程序进行相应的操作。所有的Flask程序中必须要创建一个Flask类的对象,创建Flask类对象的方式非常简单,只需要调用构造方法即可。
在Hello Flask程序中,创建Flask类对象的代码如下所示创建Flask类对象的代码如下所示。
app = Flask(__name__)
上述代码中,构造方法中传入了一个必选参数name 。name是Flask中一个特殊的变量,用于保存程序主模块或者包的名称。除了必选参数外,构造方法中还可以根据需要传入以下几个可选参数。
static_folder:用于指定存放静态文件的文件夹名称,默认值为static。 static_url_path:用于指定前端访问静态文件的路径,默认值为static_folder的名称。 template_folder:用于指定存放模板文件的文件夹名称,默认为应用程序根路径下的templates文件夹。
2.开发服务器
Flask的依赖包Werkzeug提供了一个简易的开发服务器,供开发人员在开发和测试阶段运行程序,可以暂时不配置生产服务器(如Apache)。Flask程序创建成功以后,便可以启用开发服务器测试程序是否有效。 使用开发服务器有两种方式,一种方式是通过命令行使用开发服务器,另一种方式是通过代码使用开发服务器,即调用Flask类的对象的run()方法。
app.run()
host:运行当前程序的主机名称,默认值为'127.0.0.1'或'localhost'。 port:运行当前程序的主机对应的端口号,默认值为5000。 debug:是否启用调试模式,默认值为False。
3.路由与视图
路由是一种目前主流的Web框架中应用的技术,用于帮助用户直接根据URL访问某个页面,而无须再从主页导航到这个页面。当初始化Flask类对象时,会注册程序中所有的URL规则,一旦用户在浏览器发送访问某个页面的URL请求后,服务器便会将该URL请求交给Flask程序,这时Flask程序会根据URL规则找到与之关联的视图。
在Flask中,视图是Python函数或Python类,用于对浏览器发送的请求进行处理,并返回响应内容给Web服务器。视图返回的响应内容既可以是一个包含HTML代码的字符串,也可以表单等。
例如,在Hello Flask程序中,定义视图函数及URL规则的代码如下所示。
python
@app.route("/")
def hello_flask():
return "<p>Hello, Flask!</p>"
1.4 Flask程序配置
1.4.1 常用配置项介绍
在开发Flask程序的过程中,根据不同的应用环境需要不同的配置,比如开关调试模式、密钥以及其他依赖于环境的内容,经常会将常用的属性存储在系统配置文件中,这样可以提高程序的复用性。 Flask内置了众多配置项,这些配置项都是大写形式的变量,开发人员可以通过设置这些配置项来定制程序的一些行为。
配置项 | 说明 |
---|---|
ENV | 指定应用运行的环境,默认值为'production' |
DEBUG | 启用/禁用调试模式。当ENV的值为'development'时, DEBUG的默认值为True,否则为False |
TESTING | 启用/禁用测试模式,默认值为False |
PROPAGATE_EXCEPTIONS | 显式启用/禁用异常的传播。在PROPAGATE_EXCEPTIONS未设置的情况下,若TESTING 或 DEBUG 为True,则该配置项隐式设为True |
PRESERVE_CONTEXT_ON_EXCEPTION | 当一个异常发生时,不会弹出请求上下文,默认值为None |
TRAP_HTTP_EXCEPTIONS | 若没有处理HTTPException异常的处理器,是否重新引发该异常被交互调试器处理,而并非将HTTPException作为一个简单错误响应进行返回,默认值为False |
TRAP_BAD_REQUEST_ERRORS | 尝试操作一个请求字典中不存在的键,会返回一个400页面 |
配置项 | 说明 |
---|---|
SECRET_KEY | 表示密钥,用于安全签署会话Cookie,也可用于应用或扩展的其他安全需求,它的值是一个长的随机字符串 |
SESSION_COOKIE_NAME | 会话Cookie的名称,默认值为'session' |
SESSION_COOKIE_DOMAIN | 会话Cookie会生效的域匹配规则 |
SESSION_COOKIE_PATH | 会话Cookie的路径 |
SESSION_COOKIE_HTTPONLY | 控制Cookie是否被设为HTTP only标志,默认值为True |
SESSION_COOKIE_SECURE | 控制Cookie是否被设为secure标志,默认值为True |
SESSION_COOKIE_SAMESITE | 限制外部站点的请求如何发送 cookie,默认值为None,可以被设置为'Lax'(推荐)或者'Strict' |
配置项 | 说明 |
---|---|
PERMANENT_SESSION_LIFETIME | 控制长期会话的生命周期,默认值为timedelta(days=31),即 2678400 秒 |
SESSION_REFRESH_EACH_REQUEST | 当 session.permanent 为True时,控制每个响应是否都发送Cookie,默认值为True |
USE_X_SENDFILE | 启用/禁用X-Sendfile,默认值为False。有些网络服务器, 如 Apache ,会启动X-Sendfile,以便更有效地提供数据服务。本配置项仅在使用这种服务时才有意义 |
SEND_FILE_MAX_AGE_DEFAULT | 默认缓存控制的最大期限,以秒为单位,默认值为43200(12小时)秒 |
SERVER_NAME | 设置应用绑定的主机和端口 |
APPLICATION_ROOT | 应用的根路径,默认值为'/' |
PREFERRED_URL_SCHEME | 当没有请求上下文时使用预案生成外部URL,默认值为'http' |
配置项 | 说明 |
---|---|
MAX_CONTENT_LENGTH | 设置请求数据中读取的最大字节数,默认值为None。若该配置项并未配置,且也未指定 CONTENT_LENGTH,为了安全将不会读取任何数据 |
JSON_AS_ASCII | 是否采用ASCII编码序列化对象,默认值为 True。若该配置项的值设为False,则Flask会按Unicode编码输出 |
JSON_SORT_KEYS | 是否按照字母顺序对JSON对象的键进行排序,默认值为True,这对于缓存来说是非常有用的 |
JSONIFY_PRETTYPRINT_REGULAR | 控制jsonify 响应是否输出新行、空格和缩进等排版格式的内容,以便于阅读,默认值为False。该配置项在调试模式下总是启用 |
JSONIFY_MIMETYPE | jsonify 响应的媒体类型,默认值为'application/json' |
TEMPLATES_AUTO_RELOAD | 模板更新时自动重载 |
EXPLAIN_TEMPLATE_LOADING | 是否记录模板文件如何载入调试信息,默认值为False |
MAX_COOKIE_SIZE | 设置Cookie的最大字节数,默认值为 4093。若该配置项的值小于Cookie的字节数,则发出警告;若该配置项的值为0,则关闭警告 |
1.4.2 配置信息的使用
在Flask中,若需要在程序中使用配置信息,以便对程序的一些行为进行定制,则可以采用多种方式将配置信息保存到Flask类对象的config属性中。config属性的值是一个flask.Config类的对象,flask.Config类是一个Python字典子类,它的工作方式类似于字典,既可以通过访问字典元素的方式使用配置信息,也可以通过flask.Config类提供的导入配置项的方法使用配置信息。
1.通过访问字典元素的方式使用配置文件
可以通过访问字典元素的方式获取Flask程序的配置项,并重新为该配置项赋值。例如,通过为Flask类的对象app设置配置项TESTING,以启用测试模式,代码如下所示。
app.config['TESTING'] = True
若希望一次修改多个配置项,则可以调用flask.Config从父类继承的update()方法实现。例如,通过为Flask类的对象app设置配置项TESTING和SECRET_KEY,从而为程序启用测试模式以及设置密钥,具体代码如下所示。
app.config.update(
TESTING=True,
SECRET_KEY=b'_5#y2L"F4Q8z\n\xec]/'
)
2.通过导入文件的方式使用配置文件
可以将所有的配置项存入单独的文件中,之后将该文件导入到Flask程序中。flask.Config类中提供了一些从文件中导入配置项的方法,关于这些方法的介绍如下。
from_file():从指定的文件中导入配置项,并更新配置项的值。 from_pyfile():从py文件中导入配置项,并更新配置项的值。
# 通过from_file()方法从config.json文件中导入配置项
import json
app.config.from_file("config.json", load=json.load)
# 通过from_pyfile()方法从config.py文件中导入配置项
app.config.from_pyfile("config.py")
3.通过导入对象的方式使用配置信息
可以通过定义Python类属性的方式设置配置项,之后将包含配置项的Python类或Python类实例化的对象导入到Flask程序中。flask.Config类中提供了一些从Python类中导入配置项的方法from_object(),from_object()方法用于从给定对象中导入配置项,并更新配置项的值。 需要说明的是,from_object()方法只会加载Python类中以大写字母命名的属性。如果Python类中有一个@property属性,则该类在被传递给from_object()方法之前需要进行实例化。
定义一个包含两个配置项TESTING和SECRET_KEY的类Settings,之后调用from_object()方法从Settings类中加载配置项,并在程序中使用这些配置信息,具体代码如下所示。
class Settings:
# 启用测试模式
TESTING=True
# 设置密钥
SECRET_KEY=b'_5#y2L"F4Q8z\n\xec]/'
app.config.from_object(Settings)
1.5 Flask扩展包
Flask自身并没有提供一些重要的功能模块,比如发送电子邮件、用户认证、数据库操作等,开发人员在实际开发中若需要完成这些功能,既可以使用Flask为应用增加的扩展包,也可以按照自己的需求自行开发扩展包,这样做不仅能够避免程序代码变得臃肿且复杂,而且提高了程序的可扩展性。
常用的Flask扩展包如下表所示。
扩展包 | 说明 |
---|---|
Flask-SQLalchemy | 操作数据库 |
Flask-migrate | 管理迁移数据库 |
Flask-Mail | 邮件 |
Flask-WTF | 表单 |
Flask-Bable | 提供国际化和本地支持 |
Flask-script | 插入脚本 |
Flask-Login | 认证用户状态 |
Flask-OpenID | 认证 |
Flask-RESEful | 开发REST API 工具 |
Flask-Bootstrap | 集成前端Twitter Bootstrap框架 |
Flask-Moment | 本地化日期和时间 |
Flask-Admin | 简单和可扩展的管理接口框架 |
Flask程序若希望使用某个扩展包,则需要先在当前工作环境中使用pip命令安装该扩展包。以安装扩展包Flask-SQLalchemy为例,具体安装命令如下所示。
pip install flask-sqlalchemy
扩展包Flask-SQLalchemy安装成功之后,便可以被应用引入到程序中。扩展包有着一定编写约定,它内部一般会提供一个扩展类,只要在创建扩展类对象时传入程序实例即可完成初始化过程。
以扩展包Flask-SQLalchemy提供的扩展类SQLAlchemy为例,创建SQLAlchemy对象的示例代码如下所示。
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
# 实例化Flask类
app = Flask(__name__)
# 实例化SQLAlchemy类
db = SQLAlchemy(app)
需要注意的是,尽管扩展包可以快速实现某些功能,不过有些扩展包可能会存在一些潜在的Bug,不同的扩展包之间甚至可能会出现冲突。因此我们在选择扩展包时,应该尽量从实际需求的角度出发,对扩展包的质量和兼容性多做考量,以保证效率与灵活性之间的平衡。
1.6 本章小结
本章作为本书的开篇章节,主要讲解了Flask框架的相关知识,包括Flask简介、搭建Flask开发环境、开发第一个Flask Web程序、Flask程序配置和Flask扩展包。通过学习本章的内容,希望读者能够对Flask框架建立初步的认识,为后续深入学习Flask框架做好准备工作。
1.7 习题
一,填空题
1.Flask默认以来Werkzeug工具包和()模板引擎。
2.使用()命令可以推出通过virtualenv创建的虚拟环境。
3.Flask是一个用()语言编写的微框架。
4.Flask的开发服务器默认使用的端口号为()。
5.Flask通过设置()定制程序的一些行为。
二,判断题
1.Flask自带开发服务器。()
2.Flask的依赖包Werkzeug提供了一个简易的开发服务器。()
3.Flask中的视图是Python函数或类。()
4.Flask完全兼容WSGI1.0标准。()
5.Flask的开发服务器只能通过命令行方式启动。()
三,选择题
1.下列选项中,哪个参数用于指定运行Flask程序的主机端口号?()
A.host
B.port
C.dubug
D.portal
2.下列选项中,用于在创建Flask类对象时指定模板文件存放目录的参数是()。
A.static_url_path
B.static_folder
C.template_folder
D.static_host
3.下列选项中,表示启用/禁用调式模式的配置项是()。
A.ENV
B.DEBUG
C.TESTING
D.SECRET_KEY
4.下列选项中,用于操作数据库的扩展包是()。
A.Flask-SQLAlchemy
B.Flask-Migrate
C.Flask-Mail
D.Flask-WTF
5.下列选项中,关于Flask的描述错误的是()。
A.Flask是一个由Python语言编写的微框架
B.Flask默认使用Django模板引擎将HTML页面与应用程序联系起来
C.Flask完全基于Unicode编码格式
D.Flask自带开发服务器,可以让开发者在调试Web应用程序时无须安装其他的网络服务器