一、前言

Flask诞生于2010年,是Armin ronacher(阿明·罗纳彻)用 Python 语言基于 Werkzeug 工具箱编写的轻量级Web开发框架。

Flask 本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login,数据库Flask-SQLAlchemy),都需要用第三方的扩展来实现。比如可以用 Flask 扩展加入ORM、窗体验证工具,文件上传、身份验证等。Flask 没有默认使用的数据库,你可以选择 MySQL,也可以用 NoSQL。

flask的 WSGI 工具箱采用 Werkzeug(路由模块),模板引擎则使用 Jinja2。Itsdangrous(token加密模块),Click(终端命令管理工具),flask内核本身,这5个核心模块组成 Flask 框架。

官网: https://flask.palletsprojects.com/en/2.0.x/

官方文档: https://dormousehole.readthedocs.io/en/latest/index.html

二、Flask常用第三方扩展包:

  • Flask-SQLAlchemy:操作数据库,ORM;

  • Flask-script:终端脚本工具,脚手架; ( 淘汰,官方内置脚手架:Click)

  • Flask-migrate:管理迁移数据库;

  • Flask-Session:Session存储方式指定;

  • Flask-Mail:邮件;

  • Flask-Login:认证用户状态;(django内置Auth模块,用于实现用户登录退出,)

  • Flask-OpenID:认证, OAuth;(三方授权,)

  • Flask-RESTful:开发REST API的工具;

  • Flask JSON-RPC: 开发json-rpc远程服务[过程]调用

  • Flask-Bable:提供国际化和本地化支持,翻译;

  • Flask-Moment:本地化日期和时间

  • Flask-Admin:简单而可扩展的管理接口的框架

  • Flask-Bootstrap:集成前端Twitter Bootstrap框架(前后端分离,除了admin站点,基本不用这玩意)

  • Flask-WTF:表单生成模块;(前后端分离,除了admin站点,基本不用这玩意)

  • Flask-Marshmallow:序列化(类似djangorestframework的序列化器)

可以通过 https://pypi.org/search/?c=Framework+%3A%3A+Flask 查看更多flask官方推荐的扩展

三、准备

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# anaconda创建虚拟环境
conda create -n flask python=3.9
# 进入/切换到指定名称的虚拟环境,如果不带任何参数,则默认回到全局环境base中。
# conda activate  <虚拟环境名称>
conda activate flask
# 退出当前虚拟环境
conda deactivate#安装flask,则以下命令:pip install flask -i https://pypi.douban.com/simple四、创建flask项目 1 # 1. 导入flask核心类
 2 from flask import Flask
 3
 4 # 2. 初始化web应用程序的实例对象
 5 app = Flask(__name__)
 6
 7
 8 # 4. 可以通过实例对象app提供的route路由装饰器,绑定视图与uri地址的关系
 9 @app.route("/")
10 def index():
11     # 5. 默认flask支持函数式视图,视图的函数名不能重复,否则报错!!!
12     # 视图的返回值将被flask包装成响应对象的HTML文档内容,返回给客户端。
13     return "<h1>hello flask</h1>"
14
15
16 if __name__ == '__main__':
17     # 3. 运行flask提供的测试web服务器程序
18     app.run(host="0.0.0.0", port=5000, debug=True)# 导入Flask类
from flask import Flask
 
"""
Flask类的实例化参数:
import_name      Flask程序所在的包(模块),传 __name__ 就可以
                           其可以决定 Flask 在访问静态文件时查找的路径
static_path          静态文件存储访问路径(不推荐使用,使用 static_url_path 代替)
static_url_path    静态文件的url访问路径,可以不传,默认为:/ + static_folder
static_folder        静态文件存储的文件夹,可以不传,默认为 static
template_folder  模板文件存储的文件夹,可以不传,默认为 templates
"""
app = Flask(__name__)
 
# 编写路由视图
# flask的路由是通过给视图添加装饰器的方式进行编写的。当然也可以分离到另一个文件中。
# flask的视图函数,flask中默认允许通过return返回html格式数据给客户端。
@app.route('/')
def index():
    # 返回值如果是字符串,被自动作为参数传递给response对象进行实例化返回客户端
    return "<h1>hello flask</h1>"
 
# 指定服务器IP和端口
if __name__ == '__main__':
    # 运行flask
    app.run(host="0.0.0.0", port=5000, debug=True)# 1. 导入flask核心类
from flask import Flask
 
# 2. 初始化web应用程序的实例对象
app = Flask(__name__)
 
"""第一种:flask项目加载站点配置的方式"""
# app.config["配置项"] = 配置项值
# app.config["DEBUG"] = False
 
"""第二种:flask项目加载站点配置的方式"""
# app.config是整个flask项目默认的配置属性,里面包含了所有的可用配置项,配置项的属性名都是大写字母或大小字母+下划线组成
config = {
    "DEBUG": True
}
app.config.update(config)
 
# 4. 可以通过实例对象app提供的route路由装饰器,绑定视图与uri地址的关系
@app.route("/")
def index():
    # 5. 默认flask支持函数式视图,视图的函数名不能重复,否则报错!!!
    # 视图的返回值将被flask包装成响应对象的HTML文档内容,返回给客户端。
    return "<h1>hello flask</h1>"
 
 
if __name__ == '__main__':
    # 3. 运行flask提供的测试web服务器程序
    app.run(host="0.0.0.0", port=5000)# 1. 导入flask核心类
from flask import Flask
 
# 2. 初始化web应用程序的实例对象
app = Flask(__name__)
 
# 开启debug模式
app.config["DEBUG"] = True
 
# 参数1:rule设置当前视图的路由地址
# 惨呼2:methods,设置当前视图的HTTP请求方法,允许一个或多个方法,不区分大小写
@app.route(rule="/", methods=["get", "post"])
def index():
    return "<h1>hello flask1</h1>"
 
if __name__ == '__main__':
    # 3. 运行flask提供的测试web服务器程序
    app.run(host="0.0.0.0", port=5000)# 1. 导入flask核心类
from flask import Flask
 
# 2. 初始化web应用程序的实例对象
app = Flask(__name__)
 
# 开启debug模式
app.config["DEBUG"] = True
 
@app.route(rule="/", methods=["get", "post"])
def index():
    return "<h1>hello flask1</h1>"
 
"""
路由参数的传递
小括号圈住,里面写上参数变量名
在视图中即可通过参数列表按命名来接收
接收参数时,如果没有在设置路由中设置参数的类型,则默认参数类型为字符串类型
"""
@app.route("/goods/<cid>/<gid>")
def goods(gid, cid):
    print(gid, type(gid))
    print(cid, type(cid))
    return f"显示cid={cid},gid={gid}的商品信息"
 
if __name__ == '__main__':
    # 3. 运行flask提供的测试web服务器程序
    app.run(host="0.0.0.0", port=5000)
# converters用于对路由中的参数进行格式转换与类型限定的
DEFAULT_CONVERTERS: t.Mapping[str, t.Type[BaseConverter]] = {
    "default": UnicodeConverter, # 默认类型,也就是string
    "string": UnicodeConverter, # 字符串,不包含 /
    "any": AnyConverter,    # 任意类型
    "path": PathConverter,  # 也是字符串,但是包含了 /
    "int": IntegerConverter,
    "float": FloatConverter,
    "uuid": UUIDConverter,
}
# 1. 导入flask核心类
from flask import Flask
 
# 2. 初始化web应用程序的实例对象
app = Flask(__name__)
 
# 开启debug模式
app.config["DEBUG"] = True
 
@app.route(rule="/", methods=["get", "post"])
def index():
    return "<h1>hello flask1</h1>"
 
"""
通过路由转换器来对路由参数显示格式转换和限制类型 (限制类型写到尖括号里面)
"""
@app.route("/goods/<float:cid>/<uuid:gid>")
def goods(gid, cid):
    print(gid, type(gid))
    print(cid, type(cid))
    return f"显示cid={cid},gid={gid}的商品信息"
 
if __name__ == '__main__':
    # 3. 运行flask提供的测试web服务器程序
    app.run(host="0.0.0.0", port=5000)
from werkzeug.routing.converters import BaseConverter
class RegexConverter(BaseConverter):
    def __init__(self, map, *args, **kwargs):
        super().__init__(map, *args, **kwargs)
        self.regex = args[0]app.url_map.converters["re"] = RegexConverter"""
自定义路由转换[在实际项目开发中,我们会单独准备一个python文件来保存转换器的定义代码]
"""
from werkzeug.routing.converters import BaseConverter
 
class RegexConverter(BaseConverter):
    def __init__(self, map, *args, **kwargs):
        super().__init__(map, *args, **kwargs)
        self.regex = args[0]
 
app.url_map.converters["re"] = RegexConverter
 
@app.route("/sms/<re('1[3-9]\d{9}'):mobile>")
def sms(mobile):
    return f"发送短信给手机号:{mobile}的用户"
 
@app.route("/goods/<re('\d+'):id>")
def goods(id):
    return f"显示商品id={id}的信息"#  如果要基于开发环境在终端启动项目,设置环境变量如下:
export FLASK_DEBUG=True
# 如果要基于生产环境在终端启动项目,设置环境变量如下:
# export FLASK_DEBUG=Flase
 
# 找到创建flask应用的模块路径,例如:manage.py
# 则ubuntu等Linux下的终端:
export FLASK_APP=manage.py  # 这是临时设置,如果有永久设置,可以通过/etc/profile保存
# 2. 在当前虚拟环境中,如果安装了flask模块,则可以使用全局命令flask run,即可运行flask项目
flask run # 采用默认的127.0.0.1 和 5000端口运行项目
flask run --host=0.0.0.0 --port=8088 # 可以改绑定域名IP和端口

  与django不同,flask不会提供任何的自动操作,所以需要手动创建项目目录,需要手动创建启动项目的管理文件

  例如,创建项目目录 flaskProject,在目录中创建manage.py.在pycharm中打开项目并指定上面创建的虚拟环境

  

   创建一个flask框架的启动入口文件。名字可以是app.py/run.py/main.py/index.py/manage.py/start.py

  manage.py,代码:
  

  代码分析:
  

 

  4.1、flask加载项目配置的二种方式

  

  4.2、路由的基本定义

  路由和视图的名称必须全局唯一,不能出现重复,否则报错。

  

  什么是路由?

  路由就是一种映射关系。是绑定应用程序(视图)和url地址的一种一对一的映射关系!我们在开发过程中,编写项目时所使用的路由往往是指代了框架/项目中用于完成路由功能的类,这个类一般就是路由类,简称路由。

  

  4.2.1、flask中,url可以传递路由参数,有2种方式:

  路由参数就是url路径的一部分。

  1、接收任意路由参数

  2、接收限定类型参数

  限定路由参数的类型,flask系统自带转换器编写在werkzeug/routing/converters.py文件中。底部可以看到以下字典:

  

  系统自带的转换器具体使用方式在每种转换器的注释代码中有写,请留意每种转换器初始化的参数。

  

    
转换器名称描述
string 默认类型,接受不带斜杠的任何文本
int 接受正整数
float 接受正浮点值
path 接收string但也接受斜线
uuid 接受UUID(通用唯一识别码)字符串 xxxx-xxxx-xxxxx-xxxxx

  代码:

  

  3、自定义路由参数转换器

  也叫正则匹配路由参数.

  在 web 开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要用到正则匹配,根据自己的规则去限定请求参数再进行访问

  具体实现步骤为:

  • 导入转换器基类BaseConverter:在 Flask 中,所有的路由的匹配规则都是使用转换器对象进行记录

  • 自定义转换器:自定义类继承于转换器基类BaseConverter

  • 添加转换器到默认的转换器字典DEFAULT_CONVERTERS中

  • 使用自定义转换器实现自定义匹配规则

  

  代码实现

  • 导入转换器基类

  

  • 自定义转换器
  • 添加转换器到默认的转换器字典中,并指定转换器使用时名字为: re
  • 使用转换器去实现自定义匹配规则,当前此处定义的规则是:手机号码

  5、终端运行flask项目