今天写不发相关连载了,而是将我近段时间接触到的内容做次分享。这几天,使用了开源的DashGO框架,了解到了这个开源的底层是Flask框架。所以花了点时间了解一下,现在 Web 开发领域,各种框架层出不穷,看了一下Flask的源码, 作为一款轻量级的 Python Web 框架,还是凸显了简洁、灵活的特点。今天就深入浅出地将我理解的 Flask讲解出来。
简单来说,Flask 是一个使用 Python 编写的 Web 应用框架。它就像是一个预先搭建好的 “脚手架”,为开发者提供了一系列工具、库和规则,帮助我们更轻松、高效地构建 Web 应用程序。
打个比方,如果把 Web 应用比作一座房子,那么 Flask 就像是一套建房的模板和工具包。有了它,我们不需要从最基础的一砖一瓦开始搭建,而是可以直接利用模板和工具,按照自己的需求来建造房子,大大节省了时间和精力。以下是flask的核心类图。
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 协议,可接收并处理用户请求。
当用户在浏览器中输入一个 URL 访问基于 Flask 开发的 Web 应用时,Flask 的工作流程大致如下:
接收请求:Web 服务器接收到用户的请求后,会按照 WSGI 协议将请求传递给 Flask 应用。
路由匹配:Flask 应用会根据请求中的 URL,在自己的路由表中查找对应的视图函数。路由就像是一个导航地图,不同的 URL 对应着不同的目的地(视图函数)。例如,当用户访问 “/home” 时,Flask 会找到与 “/home” 绑定的视图函数。
执行视图函数:找到对应的视图函数后,Flask 会执行该函数。视图函数是处理业务逻辑的地方,它可以从数据库中获取数据、进行计算等操作。
生成响应:视图函数执行完毕后,会返回一个响应结果(通常是 HTML 页面、JSON 数据等)。
返回响应:Flask 将响应结果通过 Web 服务器返回给用户的浏览器,浏览器接收到响应后,就会显示出相应的内容。
举个生活中的例子,这就像是我们去餐厅吃饭。我们(用户)向服务员(Web 服务器)说出自己想吃的菜(请求),服务员把点菜单交给后厨(Flask 应用)。后厨的厨师(视图函数)根据点菜单做菜(处理请求),做好后把菜(响应)交给服务员,服务员再把菜端给我们。
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 张三”。这就像是餐厅的套餐可以根据顾客的要求进行个性化定制一样。
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, 李四!”。
为了方便在视图函数中处理请求相关的数据,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()
上下文就像是我们在处理一件事情时所处的 “环境”,在这个环境中,我们可以方便地获取到处理事情所需要的各种资源和信息。当请求处理完毕后,这些上下文会被销毁,释放资源。
以上是我对其框架的初次了解,我想随着我使用dashgo框架展开应用后,应该后更深的体会。目前感受到的,Flask 作为一款轻量级的 Python Web 框架,基于 WSGI 协议工作,通过路由系统将 URL 与视图函数绑定,利用模板引擎生成动态 HTML 页面,并借助上下文机制方便地处理请求相关信息。
它的简洁、灵活和易用性使其成为 Web 开发的热门选择,无论是开发小型网站还是复杂的 Web 应用,Flask 都能发挥出很好的作用。