Flask 框架:深入浅出理解其工作原理与机制

今天写不发相关连载了,而是将我近段时间接触到的内容做次分享。这几天,使用了开源的DashGO框架,了解到了这个开源的底层是Flask框架。所以花了点时间了解一下,现在 Web 开发领域,各种框架层出不穷,看了一下Flask的源码, 作为一款轻量级的 Python Web 框架,还是凸显了简洁、灵活的特点。今天就深入浅出地将我理解的 Flask讲解出来。

一、Flask 是什么

简单来说,Flask 是一个使用 Python 编写的 Web 应用框架。它就像是一个预先搭建好的 “脚手架”,为开发者提供了一系列工具、库和规则,帮助我们更轻松、高效地构建 Web 应用程序。

打个比方,如果把 Web 应用比作一座房子,那么 Flask 就像是一套建房的模板和工具包。有了它,我们不需要从最基础的一砖一瓦开始搭建,而是可以直接利用模板和工具,按照自己的需求来建造房子,大大节省了时间和精力。以下是flask的核心类图。

Flask 框架:深入浅出理解其工作原理与机制_第1张图片

二、Flask 的工作原理

1、核心思想:WSGI 协议

Flask 的工作核心围绕着 WSGI(Web Server Gateway Interface,Web 服务器网关接口)协议。这是一种规定了 Web 服务器如何与 Web 应用程序进行通信的标准。

想象一下,Web 服务器就像是一个前台接待员,用户的请求就像是访客。当访客(用户请求)来到时,前台接待员(Web 服务器)需要把访客引导到对应的部门(Web 应用程序)。而 WSGI 协议就像是前台接待员和各部门之间沟通的 “共同语言”,确保信息能够准确、高效地传递。

Flask 作为 Web 应用程序,遵循 WSGI 协议,能够与任何符合该协议的 Web 服务器(如 Gunicorn、uWSGI 等)进行协作。

WSGI 协议的特点

简单易用:WSGI 协议的设计理念简洁,规定的接口简单明了,开发者容易理解和实现。对于 Web 应用程序开发者来说,只需要按照协议要求编写一个可调用对象(通常是函数或类的实例),该对象接收两个参数: environ(包含请求相关的环境变量)和 start_response(用于发送响应状态和响应头的函数),并返回一个响应体的迭代器即可。

def simple_app(environ, start_response):

status = '200 OK'

response_headers = [('Content-type', 'text/plain')]

start_response(status, response_headers)

return [b'Hello, WSGI!']

通用性强:WSGI 协议是 Python Web 开发领域的通用标准,只要 Web 服务器和 Web 应用程序都遵循该协议,它们之间就可以无缝协作。这意味着开发者可以根据项目需求自由选择合适的 Web 服务器和 Web 应用框架,而不必担心兼容性问题。例如,Flask 应用可以搭配 Gunicorn 服务器,也可以搭配 uWSGI 服务器。

分离关注点:WSGI 协议清晰地将 Web 服务器的功能(如接收 TCP 连接、解析 HTTP 请求等)和 Web 应用程序的功能(如处理业务逻辑、生成响应等)分离开来。Web 服务器专注于处理网络层面的任务,Web 应用程序专注于处理业务逻辑,两者通过 WSGI 协议进行通信,使得各自的开发和维护更加独立、高效。

可扩展性好:基于 WSGI 协议可以构建中间件(Middleware),中间件位于 Web 服务器和 Web 应用程序之间,能够对请求和响应进行处理和转换,如实现身份验证、日志记录、URL 重写等功能。中间件的存在使得 WSGI 生态系统具有很强的可扩展性,开发者可以根据需要组合不同的中间件来增强应用的功能。

以下是一个简单的基于 WSGI 协议的 Flask 应用启动示例,展示 Flask 如何通过 WSGI 与服务器交互:


from flask import Flask

app = Flask(__name__)

@app.route('/')

def hello_world():

return 'Hello, World!'

if __name__ == '__main__':

# 启动内置的开发服务器,遵循WSGI协议

app.run()

当运行该代码后,Flask 会启动一个内置的简易 Web 服务器,该服务器遵循 WSGI 协议,可接收并处理用户请求。

2、请求处理流程

当用户在浏览器中输入一个 URL 访问基于 Flask 开发的 Web 应用时,Flask 的工作流程大致如下:

接收请求:Web 服务器接收到用户的请求后,会按照 WSGI 协议将请求传递给 Flask 应用。

路由匹配:Flask 应用会根据请求中的 URL,在自己的路由表中查找对应的视图函数。路由就像是一个导航地图,不同的 URL 对应着不同的目的地(视图函数)。例如,当用户访问 “/home” 时,Flask 会找到与 “/home” 绑定的视图函数。

执行视图函数:找到对应的视图函数后,Flask 会执行该函数。视图函数是处理业务逻辑的地方,它可以从数据库中获取数据、进行计算等操作。

生成响应:视图函数执行完毕后,会返回一个响应结果(通常是 HTML 页面、JSON 数据等)。

返回响应:Flask 将响应结果通过 Web 服务器返回给用户的浏览器,浏览器接收到响应后,就会显示出相应的内容。

举个生活中的例子,这就像是我们去餐厅吃饭。我们(用户)向服务员(Web 服务器)说出自己想吃的菜(请求),服务员把点菜单交给后厨(Flask 应用)。后厨的厨师(视图函数)根据点菜单做菜(处理请求),做好后把菜(响应)交给服务员,服务员再把菜端给我们。

三、Flask 的工作机制

1、路由系统

Flask 的路由系统是其核心机制之一,它负责将 URL 与视图函数进行绑定。开发者可以通过装饰器@app.route()来定义路由。



from flask import Flask

app = Flask(__name__)

@app.route('/hello')

def hello():

return 'Hello, Flask!'

if __name__ == '__main__':

app.run()

在这个例子中,@app.route('/hello')表示当用户访问 “/hello” 这个 URL 时,会执行下面的hello()函数,并返回 “Hello, Flask!”。运行代码后,在浏览器中访问http://127.0.0.1:5000/hello,就能看到返回的内容。

路由系统还支持动态 URL,例如:


from flask import Flask

app = Flask(__name__)

@app.route('/user/')

def show_user_profile(username):

return f'User {username}'

if __name__ == '__main__':

app.run()

当用户访问 “/user/ 张三” 时,username参数就会被赋值为 “张三”,视图函数会返回 “User 张三”。这就像是餐厅的套餐可以根据顾客的要求进行个性化定制一样。

2、模板引擎(Jinja2)

Flask 集成了 Jinja2 模板引擎,用于处理 HTML 页面的生成。模板引擎可以将动态数据嵌入到静态的 HTML 模板中,生成最终的 HTML 页面返回给用户。

首先,需要创建一个 templates 文件夹(Flask 默认会从该文件夹寻找模板文件),在里面创建一个 user.html 文件,内容如下:








User Info





Hello, {{ username }}!

然后在 Python 代码中使用模板引擎:


from flask import Flask, render_template

app = Flask(__name__)

@app.route('/user/')

def show_user_profile(username):

# 渲染模板,并传递参数username

return render_template('user.html', username=username)

if __name__ == '__main__':

app.run()

形象地说,模板就像是一个带有占位符的信件模板,我们可以根据不同的收件人(动态数据)填写不同的内容,然后生成一封完整的信件(HTML 页面)。上述例子中,“{{username}}” 就是占位符,当视图函数传递不同的用户名时,模板引擎会将占位符替换成相应的用户名。访问http://127.0.0.1:5000/user/李四,页面会显示 “Hello, 李四!”。

3、请求上下文与应用上下文

为了方便在视图函数中处理请求相关的数据,Flask 引入了上下文的概念。上下文就像是一个临时的存储空间,在处理请求的过程中,我们可以从中获取到当前请求的相关信息。


from flask import Flask, request, current_app

app = Flask(__name__)

# 设置应用配置

app.config['SECRET_KEY'] = 'mysecretkey'

@app.route('/login', methods=['GET', 'POST'])

def login():

if request.method == 'POST':

# 通过请求上下文获取表单数据

username = request.form.get('username')

password = request.form.get('password')

return f'Login attempt with username: {username}'

else:

# 通过应用上下文获取应用配置

secret_key = current_app.config['SECRET_KEY']

return f'This is login page. Secret key: {secret_key}'

if __name__ == '__main__':

app.run()
  • 请求上下文:包含了与当前请求相关的信息,如请求的 URL、请求方法(GET、POST 等)、表单数据等。我们可以通过request对象来访问这些信息。上述代码中,通过request.method获取请求方法,request.form.get()获取表单数据。
  • 应用上下文:包含了与当前应用相关的信息,如应用的配置、数据库连接等。我们可以通过current_app对象来访问这些信息。代码中通过current_app.config获取应用的配置信息。

上下文就像是我们在处理一件事情时所处的 “环境”,在这个环境中,我们可以方便地获取到处理事情所需要的各种资源和信息。当请求处理完毕后,这些上下文会被销毁,释放资源。

四、Flask 的优势

  • 轻量级:Flask 的核心功能简洁,没有过多的冗余组件,开发者可以根据自己的需求灵活地选择和扩展功能。这就像是一个轻便的工具箱,我们可以只带上需要的工具出门。
  • 易学易用:Flask 的 API 设计简洁明了,对于新手来说容易上手。它的文档丰富且易懂,能够帮助开发者快速掌握使用方法。
  • 灵活性高:Flask 不强制使用特定的数据库、模板引擎等,开发者可以根据项目需求选择合适的工具和库进行集成。
  • 扩展性强:Flask 有大量的扩展库(如 Flask-SQLAlchemy 用于数据库操作、Flask-Login 用于用户认证等),这些扩展可以为 Flask 增加各种功能,满足不同项目的需求。

最后小结

以上是我对其框架的初次了解,我想随着我使用dashgo框架展开应用后,应该后更深的体会。目前感受到的,Flask 作为一款轻量级的 Python Web 框架,基于 WSGI 协议工作,通过路由系统将 URL 与视图函数绑定,利用模板引擎生成动态 HTML 页面,并借助上下文机制方便地处理请求相关信息。

它的简洁、灵活和易用性使其成为 Web 开发的热门选择,无论是开发小型网站还是复杂的 Web 应用,Flask 都能发挥出很好的作用。

你可能感兴趣的:(熬之滴水穿石,flask,python,后端)