首頁 >後端開發 >Python教學 >Python學習之解析Flask運作原理(圖文詳解)

Python學習之解析Flask運作原理(圖文詳解)

WBOY
WBOY轉載
2022-03-01 18:23:415069瀏覽

本篇文章為大家帶來了關於python的相關知識,其中主要介紹了Flask的運行原理相關​​問題,對Flask的運行原理做一簡要解析,以增強對Flask的了解,希望對大家有幫助。

Python學習之解析Flask運作原理(圖文詳解)

 推薦學習:python學習教學

  所有的Python Web框架都要遵循WSGI 協定,在這裡還是要簡單回顧一下WSGI 的核心概念。

  WSGI 中有一個非常重要的概念:每個Python Web應用程式都是一個可呼叫(callable)的物件。在 flask 中,這個物件就是 app = Flask(name) 建立出來的 app,就是下圖中的綠色Application部分。要運行web應用,必須有 web server,例如我們熟悉的apache、nginx,或者python中的gunicorn,我們下面要講到的werkzeug提供的WSGIServer,它們是下圖的黃色Server部分。
Python學習之解析Flask運作原理(圖文詳解)
  Server和Application之間怎麼通信,就是WSGI的功能。它規定了app(environ, start_response) 的接口,server會調用application,並傳給它兩個參數:environ 包含了請求的所有信息,start_response 是application 處理完之後需要調用的函數,參數是狀態碼、響應頭部還有錯誤訊息。

  WSGI application 非常重要的特點是:它是可以嵌套的。換句話說,可以寫個application,它做的事情就是呼叫另一個 application,然後再回傳(類似一個 proxy)。一般來說,嵌套的最後一層是業務應用,中間就是 middleware。這樣的好處是,可以解耦業務邏輯和其他功能,例如限流、認證、序列化等都實現成不同的中間層,不同的中間層和業務邏輯是不相關的,可以獨立維護;而且用戶也可以動態地組合不同的中間層來滿足不同的需求。
Python學習之解析Flask運作原理(圖文詳解)
  Flask基於Werkzeug WSGI工具箱和Jinja2 範本引擎。 Flask使用BSD授權。 Flask也被稱為“microframework”,因為它使用簡單的核心,並用extension增加其他功能。 Flask沒有預設使用的資料庫、窗體驗證工具。然而,Flask保留了擴增的彈性,可以用Flask-extension加入這些功能:ORM、窗體驗證工具、檔案上傳、各種開放式身分驗證技術。我們可以這麼理解,Flask是一個核心,而其他功能則是一些插件,需要什麼功能,只要找到對應的插件,將其插入核心就能夠實現該功能了。

  Flask是怎麼將程式碼轉換為我們可見的Web網頁的。首先,我們得先從Web程式的一般流程來看,對於我們的Web應用來說,當客戶端想要取得動態資源時,(例如ASP和PHP這類語言寫的網站),這個時候就會發起一個HTTP請求(例如用瀏覽器存取一個URL),此時Web應用程式就會在伺服器後台進行相應的業務處理(例如對資料庫進行操作或是進行一些計算操作等),取出使用者需要的數據,生成對應的HTTP回應(當然,如果存取的是靜態資源,伺服器則會直接傳回使用者所需的資源,不會進行業務處理)。整個處理工程如下所示:
Python學習之解析Flask運作原理(圖文詳解)
  在實際的應用中,不同的請求可能會呼叫相同的處理邏輯。這裡有著相同業務處理邏輯的HTTP請求可以用一類URL來識別。例如在我們的部落格網站中,對於所有想要取得Articles內容的請求而言,可以用 articles/這類URL來表示,這裡的article_id用來區分不同的article。接著在後台定義一個get_article(article_id)的函數,用來取得article對應的數據,此外還需要建立URL和函數之間的一一對應關係。這就是Web開發中所謂的路由分發,如下圖所示:
Python學習之解析Flask運作原理(圖文詳解)
  在Flask中,使用werkzeug來做路由分發,werkzeug是Flask使用的底層WSGI庫(WSGI,全名為Web Server Gateway interface,或Python Web Server Gateway Interface,是為Python 語言定義的Web伺服器和Web應用程式之間的簡單而通用的介面)。
  WSGI將Web服務分成兩個部分:伺服器和應用程式。 WGSI伺服器只負責與網路相關的兩件事:接收瀏覽器的HTTP請求、向瀏覽器發送HTTP應答;而對HTTP請求的具體處理邏輯,則透過呼叫WSGI應用程式進行。 WSGI工作流程如下圖所示:
Python學習之解析Flask運作原理(圖文詳解)
  在Flask中,路由分發的程式碼寫起來十分簡單,如下:

# 管理员注销页面
@main.route('/logout')
def logout():
    dm = DataManager()
    currentUsers = dm.getUsers('0')
    print(currentUsers[0])
    return render_template('currentUsers.html', users=currentUsers)

  透過業務邏輯函數取得我們所需的資料後,伺服器將會根據這些資料來產生HTTP回應(對於Web應用來說,一般就是一個HTML文件,這個是可以直接被我們的客戶端,也就是瀏覽器直接讀取並解釋的)。在網路開發中,常規的做法是將取得的資料傳入Web應用程式提供的一個HTML範本檔案中,經過範本系統的渲染後最終得到我們所需要的HTML回應檔。
  一般情況下,雖然請求不同,但是回應中的資料的展示方式是相同的,通俗點說就是除了我們請求獲得的資料不一樣外,其他都是一樣的,那麼我們就可以設計一個模板(除了資料內容可以改動,其他都是固定的HTML檔)。我們以部落格網站為例,對不同article而言,其具體article content雖然不同,但頁面展示的內容除了所要求的資料外都是一樣的,都有標題攔,內容欄等。也就是說,對於article來說,我們只需提供一個HTML模板,然後傳入不同article數據,即可得到不同的HTTP回應。這就是所謂的模板渲染,如下圖所示:
Python學習之解析Flask運作原理(圖文詳解)
  在Flask中使用Jinja2模板渲染引擎來做模板渲染(Jinja2是基於python的模板引擎,功能比較類似於於PHP的smarty ,J2ee的Freemarker和velocity。它能完全支援unicode,並具有整合的沙箱執行環境,應用廣泛。jinja2使用BSD授權)。 Jinja2的工作流程如下圖所示:
Python學習之解析Flask運作原理(圖文詳解)
  在Flask中,模板渲染的程式碼寫起來也是十分的便捷,程式碼如下:

@app.route('/articles/<article_id>/') 
defget_article(article_id):
returnrender_template('path/to/template.html', data_needed)</article_id>

  在Flask中,我們處理一個請求的流程就是,先根據使用者提交的URL來決定由哪個業務邏輯函數來處理,然後在函數中進行操作,取得所需的資料。再將取得的資料傳給對應的範本文件中,由Jinja2負責渲染得到HTTP回應內容,也就是HTTP回應的HTML文件,接著由Flask回傳回應內容。
  下面主要以實例項目對Flask運作原理做一簡要解析。在實例專案中,使用到了程式工廠函數和藍本。專案目錄結構如下:
Python學習之解析Flask運作原理(圖文詳解)
  在manager.py檔案中,定義了專案啟動的入口函數:

# 确保服务器只会在该脚本被 Python 解释器直接执行的时候才会运行,而不是作为模块导入的时候。
if __name__ == '__main__':
    # 启用cmd命令行
    # manager.run()
    app.run(host='0.0.0.0', port=9000, debug=True)

同时,在该文件中创建了工厂方法实例:

	app = create_app()

  在工程方法中,对数据库进行了相关配置,创建了前端导航栏,同时对所创建的蓝本进行了注册。在创建的蓝本中主要涉及授权、路由及错误处理模块。

# 构造工厂方法
def create_app():
    # 在这里__name__ == __main__
    app = Flask(__name__)
    app.url_map.converters['regex'] = RegexConverter
    # 防止跨站攻击 注:为了增强安全性,密钥不应直接写入代码,而应该保存在环境变量中
    # app.config['SECRET_KEY'] = 'hard to guess string SUNNY2017'
    # app.secret_key = 'Sunny123456'

    # flask提供的读取外部文件
    app.config.from_pyfile('config')

    # basedir = os.path.abspath(os.path.dirname(__file__))
    # print(basedir)

    # 配置数据库连接
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://lmapp:lmapp@localhost/smp'
    app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

    nav.register_element('top', Navbar(u'APP安盾',
                                       View(u'当前在线', 'main.index'),
                                       View(u'全部用户', 'main.all_users'),
                                       View(u'注销', 'main.logout'),
                                       View(u'修改密码', 'main.chgpwd'),
                                       ))
    nav.init_app(app)
    db.init_app(app)
    bootstrap.init_app(app)
    # init_views(app)
    from .auth import auth as auth_blueprint
    from .main import main as main_blueprint
    # 注册蓝本 url_prefix='/auth'
    app.register_blueprint(auth_blueprint,)
    app.register_blueprint(main_blueprint, static_folder='static')
    return app

 推荐学习:python教程

以上是Python學習之解析Flask運作原理(圖文詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除