使用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的一些新功能和新特性后,我們來嘗試使用這些新特性創建一個簡單的項目

該項目上創建一個應用,應用上注冊了兩個藍圖,分別為v1v2(代表兩個不同的版本),v1藍圖和v2藍圖上分別注冊了子藍圖adminuser,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官方文檔中查閱。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM