python flask开发笔记
简述flask优势
轻量级:核心简单,便于定制和扩展
灵活:支持多种模板引擎,易于集成各种数据库
安全:内置防止跨域请求伪造保护机制 csrf
容易上手:文档清洗,便于上手
社区支持:拥有活跃的社区和丰富的第三方扩展
flask框架主要依赖组件
Werkzeug:web服务器网关接口工具库,提供许多于http协议相关功能
Jinja2:强大的模板引擎,用于生成html,xml或其他标记语言,flask使用jinja2来渲染模板
itsdangerous:用于安全地签名和验证数据库,flask使用它来实现如session等功能
click:用于创建命令行界面的python库
(可选) Flask-SQLAlchemy,用于简化数据库操作
(可选) Flask-WTF,用于处理web表单
(可选) Flask-Login,用于管理用户登录状态
(可选) Flask-RESTful,用于快速构建RESTful Api
flask蓝图作用
业务分层归类
代码逻辑层次清晰(模块化组织代码)
简化大型应用开发
支持URL前缀和子域名,方便管理和组织相关路由
提升开发效率,以及灵活性
促进团队协作,分工更容易
列举flask第三方组件
fask-SQLAlchemy
flask-WTF
flask-Login
flask-RESTful
flask-SocketIO:支持WebSocket通信,实现实时双向通信
flask-Bcrypt:提供密码hash功能,用于安全地存储用户密码
flask-mail:继承邮件发送功能
flask-admin:提供简易的管理界面
falsk-limiter:限制请求速率,防止恶意请求和DDos攻击
flask-caching:提供缓存支持,提高应用性能
flask-uploads:简化文件上传功能,支持多种存储后端
flask-jwt-extended:提供jwt支持用于用户认证和授权
简述flask上下文管理流程
请求上下文
请求到达
创建请求上下文:创建requestContext对象,压入栈中
绑定请求对象:将request对象绑定到当前线程或协程
处理请求
响应生成
弹出请求上下文
应用上下文
创建应用上下文:在请求上下文创建前后(appContext)
绑定应用上下文到当前线程或者协程
访问应用集资源:通过current_app对象
弹出应用上下文
flask中g的作用
g是flask中的一个全局变量,应用于存储在请求处理过程中需要共享的数据,g对象是应用上下文的一部分,它在请求开始是被创建,并在请求结束时被销毁,保证数据的线程安全性
存储请求相关的全局数据
存储用户认证信息
存储临时数据
flask中上下文管理主要涉及到了哪些相关的类,并描述类主要作用
1. `Context`
2. `RequestContext`
request:绑定当前的 Request 对象。push() 和 pop():用于将上下文推入和弹出栈。3. `AppContext`
app:绑定当前的 Flask 应用实例。g:绑定当前的全局变量 g 对象。push() 和 pop():用于将上下文推入和弹出栈。4. `LocalStack`
push() 和 pop():用于操作栈中的上下文对象。top:获取栈顶的上下文对象。5. `LocalProxy`
request:代理当前的 Request 对象。current_app:代理当前的 Flask 应用实例。g:代理当前的全局变量 g 对象。上下文管理流程简述
1. 请求到达:客户端发送请求到服务器。
2. 创建并推送请求上下文:Flask 创建一个 RequestContext 对象并将其推入 LocalStack。
3. 创建并推送应用上下文:如果当前没有应用上下文,Flask 还会创建一个 AppContext 对象并推入栈中。
4. 处理请求:视图函数及其他处理逻辑可以访问 request、current_app 和 g 等对象。
5. 响应生成并弹出上下文:请求处理完毕后,Flask 将相应的上下文对象从栈中弹出。
flask为什么要把local对象中的值stack维护成一个列表
在 Flask 中,Local 对象中的值被维护成一个列表(实际上是一个栈结构)
1. **支持嵌套上下文**
Flask 允许在处理请求时存在多个嵌套的上下文。例如,在一个请求处理过程中,可能会触发另一个子请求或使用某些特定的功能(如测试框架中的测试用例)。通过使用栈结构,Flask 能够正确地管理这些嵌套上下文,确保每个上下文都能独立存在并且不会相互干扰。
2. **上下文的进入和退出管理**
栈结构非常适合管理资源的进入和退出。当进入一个新的上下文时,可以将其推入栈中;当退出上下文时,可以将其从栈中弹出。这种方式确保了资源的正确分配和释放,避免了资源泄漏。
3. **线程安全性**
Flask 使用 Local 对象来存储线程局部变量,这意味着每个线程都有自己独立的上下文栈。通过使用栈结构,Flask 能够确保在多线程环境下,每个线程的上下文都是独立的,不会相互影响。
4. **简化上下文切换**
栈结构使得上下文的切换变得非常简单。当需要切换到新的上下文时,只需将新的上下文对象推入栈中;当需要返回到之前的上下文时,只需将当前上下文对象弹出栈即可。这种方式简化了上下文管理的逻辑,提高了代码的可读性和可维护性。
5. **支持上下文的动态管理**
在实际应用中,上下文的创建和销毁可能是动态的。通过使用栈结构,Flask 能够灵活地管理这些动态变化的上下文,确保在任何时刻都能正确地访问到当前有效的上下文。
总结
将 Local 对象中的值维护成一个列表(栈结构),Flask 能够有效地管理嵌套上下文、简化上下文的进入和退出管理、确保线程安全性、简化上下文切换以及支持上下文的动态管理。这些优点使得 Flask 能够在复杂的请求处理过程中保持高效和可靠
flask中多应用app是怎么完成的
Flask 支持多应用的管理方式包括使用蓝图、创建多个 Flask 实例、使用 WSGI 服务器以及应用工厂模式
flask中实现websocket需要什么组件
在 Flask 中实现 WebSocket 功能,主要需要 Flask-SocketIO 扩展来简化集成过程,并且通常需要一个 WebSocket 客户端库来进行客户端通信。在生产环境中,可能还需要使用更强大的 WebSocket 服务器来处理高并发和稳定性问题
flask框架默认session处理机制
Flask 默认的 session 处理机制依赖于客户端的 cookie,通过加密和签名确保数据的安全性,
服务器端不直接存储 session 数据,而是通过 session ID 来识别和获取对应的 session 数据。这种机制简单且高效,适用于大多数应用场景
加密
加密是一种将数据转换为不可读格式的过程,只有拥有密钥的人才能将其还原
签名
基于原数据生成一个hash,然后再由私钥进行加密,生成签名。接收方可使用公钥进行解密签名,并验证数据完整性
解释flask中的local对象和threading.local对象的区别
flask中的local对象是基于threading.local实现的,都是用户于存储线程局部变量的
在实际开发中,如果是在 Flask 应用中,推荐使用 flask.local.Local 或者直接利用 Flask 提供的上下文管理机制(如 request、session 等),而不是直接使用 threading.local
阐述flask中的blinker是什么
blinker是flask中信号组件库,允许某些发送者通知一组接收者某些操作已经发生,便于各组件之间的交互于解耦
blinker在flask中的应用:
请求上下文的信号 通知
模板渲染的的信号通知
扩展于插件的集成
blinker的优势:
解耦
灵活性
可扩展性
滥用可能会导致代码阅读性不高,难以维护
flask实现文件上传
from flask import Flask, request, redirect, url_for, flash, render_template
import os
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads' # 设置上传文件夹
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 设置上传文件大小限制为16MB
# 确保上传文件夹存在
if not os.path.exists(app.config['UPLOAD_FOLDER']):
os.makedirs(app.config['UPLOAD_FOLDER'])
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# 检查是否有文件部分
if 'file' not in request.files:
flash('没有文件部分')
return redirect(request.url)
file = request.files['file']
# 如果用户没有选择文件,浏览器也会提交一个空的part,没有文件名
if file.filename == '':
flash('没有选择的文件')
return redirect(request.url)
if file:
filename = secure_filename(file.filename) # 使用werkzeug.utils.secure_filename确保文件名安全
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('文件上传成功')
return redirect(url_for('upload_file'))
return render_template('upload.html')
if __name__ == '__main__':
app.run(debug=True)
flask实现文件下载
from flask import Flask, send_from_directory, request, abort
import os
app = Flask(__name__)
UPLOAD_FOLDER = 'uploads' # 设置上传文件夹的路径
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
@app.route('/download/<filename>', methods=['GET'])
def download_file(filename):
# 检查文件是否存在
if not os.path.isfile(os.path.join(app.config['UPLOAD_FOLDER'], filename)):
abort(404) # 文件不存在,返回404错误
# 发送文件
return send_from_directory(app.config['UPLOAD_FOLDER'], filename, as_attachment=True)
flask中的勾子函数
before_first_request 第一次请求之前
before_request 每次请求之前
after_request 每次请求之后
teardown_request 请求结束时执行
flask中请求钩子和上下文钩子的区别
作者:2401_88593882