使用Flask2.0创建一个简单的项目
Flask2.0重要改动
据JetBrains Python开发者社区调查,Flask是近年来最常用的Python Web开发框架之一。Flask2.0.0
于2021年5月份发布,共推出了三十多个版本变更,主要变更如下:
三大核心特性
- 嵌套蓝图
- 异步视图
- 快捷路由装饰器
其他重要变化
- 不再支持Python2和Python3.5
- 新增了Type hinting,有助于IDE自动补全
- 支持从任意文件加载器导入配置(导入方法为
Config.from_file()
) - 优化浏览器缓存控制,静态文件变动后,重启应用会立即更新资源(不再需要手动清缓存)
- Werkzeug的multipart解析性能提高了15倍
jsonify
支持序列化decimal.Decimal
格式的数据(该改动在Flask2.0.2版本添加)
安装
本文使用Python3.9(部分特性需要3.9以上版本支持)
pip install -U flask
若是想用Flask2.0的异步功能,则需要安装额外依赖(主要是asgiref
包)
pip install -U flask[async]
三大核心特性讲解
上面我列出了Flask2.0新增的三大核心特性,接下来我会通过代码来说明这三大特性的特点和使用方法,并尝试根据这三大特性来编写一个简单的应用。
嵌套蓝图
Flask使用蓝图Blueprint对程序进行模块化处理。一个大型项目通常都会使用蓝图来规划不同的模块,而嵌套蓝图的作用就是可以更细地去划分管理不同的模块。
一个应用可以注册多个蓝图,而现在蓝图也可以注册多个子蓝图(子蓝图还可以注册孙子蓝图,可以嵌套很多层,支持无限嵌套),对项目进行多层模块化组织。
app = Flask(__name__) # 创建一个应用
a = Blueprint('a', __name__) # 创建父蓝图
b = Blueprint('b', __name__) # 创建子蓝图
a.register_blueprint(b) # 将子蓝图注册到父蓝图上
app.register_blueprint(a) # 将父蓝图注册到应用上
上面例子只是简单示范嵌套蓝图的使用,实际开发中一般不会将应用和蓝图写到同一个文件内。
异步视图
Flask2.0加入了基本的async/await支持(目前只是基于asgiref来实现异步),因此我们可以自己去定义异步视图。
异步视图有很多优点,比如能够在不使用Python线程的情况下为数百个连接提供服务,允许使用慢速流、长轮询和其他的响应类型等等。
import asyncio
from flask import Flask
app = Flask(__name__)
@app.route('/')
async def hello():
await asyncio.sleep(1)
return 'hello flask'
if __name__ == '__main__':
app.run()
快捷路由装饰器
新增了以下路由装饰器:
- app.get()
- app.post()
- app.delete()
- app.put()
- app.patch()
上面的路由装饰器对应之前的app.route()
装饰器,如app.post()
相当于app.route(methods=['POST'])
。需要注意的是,这些快捷路由装饰器只能处理单个方法类型的请求,如果需要处理多种方法类型的请求,请用app.route()
装饰器。
from flask import Flask
app = Flask(__name__)
@app.post('/hello') # 快捷路由装饰器
def hello():
return 'Hello Flask'
@app.route('/hello2', methods=['GET', 'POST']) # 多种请求类型
def hello2():
return 'Hello Flask2'
if __name__ == '__main__':
app.run()
创建一个简单的项目
在了解了Flask2.0的一些新功能和新特性后,我们来尝试使用这些新特性创建一个简单的项目
该项目上创建一个应用,应用上注册了两个蓝图,分别为v1
和v2
(代表两个不同的版本),v1蓝图和v2蓝图上分别注册了子蓝图admin
和user
,v1版本的视图函数使用以往的写法,v2版本的视图函数使用新的特性,以便大家进行对比。
项目的目录结构如下
flask2
/app
/v1
__init__.py
admin.py
user.py
/v2
__init__.py
admin.py
user.py
__init__.py
manager.py
manager.py文件用于启动我们的Web服务
from flask import Flask
from app import v1, v2
app = Flask(__name__) # 创建Flask的主app
app.register_blueprint(v1.bp) # 注册蓝图
app.register_blueprint(v2.bp)
@app.route('/')
def index():
return 'Hello World'
if __name__ == '__main__':
app.run(debug=True)
/app/v1/__init__.py,该文件主要用于加载项目包时创建父蓝图和注册子蓝图
from flask import Blueprint
from app.v1 import admin, user
bp = Blueprint('v1', __name__, url_prefix='/v1') # 创建父蓝图v1
bp.register_blueprint(admin.api) # 注册子蓝图admin
bp.register_blueprint(user.api) # 注册子蓝图user
@bp.route('')
def index():
"""父蓝图视图函数"""
return 'here is v1.'
/app/v1/admin.py
from flask import Blueprint
api = Blueprint('admin', __name__, url_prefix='/admin') # 创建一个蓝图
@api.route('')
def index():
return 'here is admin v1.'
@api.route('/hello', methods=['POST'])
def hello():
return 'hello admin v1'
/app/v1/user.py
from flask import Blueprint
api = Blueprint('user', __name__, url_prefix='/user') # 创建一个蓝图
@api.route('')
def index():
return 'here is user v1.'
@api.route('/hello', methods=['GET', 'POST']) # 多种请求类型
def hello():
return 'hello user v1.'
/app/v2/__init__.py
from flask import Blueprint
from app.v2 import admin, user
bp = Blueprint('v2', __name__, url_prefix='/v2') # 创建父蓝图v2
bp.register_blueprint(admin.api) # 注册子蓝图admin
bp.register_blueprint(user.api) # 注册子蓝图user
@bp.route('')
def index():
"""父蓝图视图函数"""
return 'here is v2.'
/app/v2/admin.py
import asyncio
from flask import Blueprint
api = Blueprint('admin', __name__, url_prefix='/admin') # 创建一个蓝图
@api.get('') # 快捷路由装饰器
def index():
return 'here is admin v2.'
@api.post('/hello')
async def hello():
"""异步视图"""
await asyncio.sleep(1)
return 'hello admin v2.'
/app/v2/user.py
import asyncio
from flask import Blueprint
api = Blueprint('user', __name__, url_prefix='/user') # 创建一个蓝图
@api.get('')
def index():
return 'here is user v2.'
@api.post('/hello')
async def hello():
await asyncio.sleep(1)
return 'hello user v2.'
项目代码我放到我的Github上,有需要的话可以去上面取。
代码编写完后运行manager.py文件启动项目,项目url为 http://localhost:5000
可以使用python
或者Postman
软件来发送相关的请求,如发送一个GET请求到 http://localhost:5000/v1/user
,或者发送一个POST请求到 http://localhost:5000/v2/user/hello
,会返回相关的数据。(如果返回的结果是404或405,则注意是否url或者请求方法错了)
以上就是Flask2.0的新特性介绍,如果想学习更多关于Flask的知识点,可以去Flask官方文档中查阅。