一、路由参数与请求方法
Flask 路由允许定义多种参数类型,并通过 methods 属性限制请求方法。
1. 路由参数类型:
除了默认的 string,Flask 还支持:
int: 匹配整数,自动转换为 Python int 类型。非数字输入会返回 404。
float: 匹配浮点数,自动转换为 Python float 类型。
path: 匹配包含斜杠 / 的路径(斜杠不被视为参数分隔符),但会将其转换为字符串。
区别于默认 string: string 类型会把 / 视为路径分隔符,导致参数截断。
uuid: 匹配符合 UUID 格式的字符串,并自动转换为 UUID 对象。严格校验格式。
any: 限制参数值只能是预定义元组中的一个(如 any(c,d,e)),类似于枚举。
总结: Flask 的路由参数类型支持精准匹配和自动类型转换,优于 Django 默认将所有 URL 参数视为字符串。
2. 请求方法(HTTP动词):
默认情况下,Flask 路由支持 GET 和 HEAD 请求。
限制方法: 使用 methods 属性(列表)来指定允许的 HTTP 方法,例如 methods=['GET', 'POST']。
HTTP 状态码: 不允许的方法请求会返回 405 Method Not Allowed 错误。
常见 HTTP 方法及其语义:
GET: 获取资源(检索)。
POST: 提交/创建资源(提交数据,如表单提交)。
PUT: 创建或更新资源(整体替换)。
DELETE: 删除资源。
HEAD: 获取资源的元数据(如响应头),不返回响应体。
RESTful API 实践: 通过不同 HTTP 方法操作同一资源路径,实现高内聚,例如 /user 路径,GET 获取用户,POST 创建用户,PUT 更新用户,DELETE 删除用户。
3. 反向解析(url_for):
功能: 根据视图函数名称(或端点名)动态生成 URL,避免硬编码。
基本用法: url_for('视图函数名')。默认的端点名就是视图函数名。
带参数用法: url_for('视图函数名', 参数名1=值1, 参数名2=值2, ...),参数会作为查询字符串或路径参数拼接到 URL 中。
在模板中使用: 使用 Jinja2 语法 {。
{ url_for('视图函数名', 参数名=值) }}
二、请求与响应
1. 请求对象 (request):
内置对象: Flask 的 request 对象是内置的,无需作为函数参数传入。
导入: 从 flask 模块导入 from flask import request。
底层: request 实际上是一个 localproxy,代理了底层的 WSGI 请求对象。
常用属性及获取数据:
request.method: 获取请求方法(如 'GET', 'POST')。
request.data: 获取请求体的原始二进制数据。
request.args: 获取 GET 请求参数(查询字符串),类型是 ImmutableMultiDict。
request.args.get('key'): 安全获取参数,不存在返回 None。
request.args.getlist('key'): 获取同名参数的所有值(列表)。
注意: 即使是 POST 请求,只要 URL 中有查询字符串,request.args 也能获取。
request.form: 获取 POST 表单数据(Content-Type: application/x-www-form-urlencoded 或 multipart/form-data),类型也是 ImmutableMultiDict。
request.files: 获取文件上传数据,类型是 FileStorage 对象(与 Django 的 InMemoryUploadedFile 不同)。
request.cookies: 获取请求中的 Cookie。
request.json: 获取 JSON 格式的请求体数据(Content-Type: application/json)。
request.remote_addr: 获取客户端 IP 地址。
request.user_agent: 获取客户端的用户代理字符串(浏览器标识)。
request.url: 获取完整的请求 URL。
2. 响应对象 (response):
Flask 视图函数支持多种返回类型,最终都会被 Flask 包装成 Response 对象。
返回类型:
字符串: Flask 会自动将其包装为 Response 对象,并设置 Content-Type: text/html。
render_template() 渲染的模板: 返回的是 HTML 字符串,也会被自动包装。
元组: 可返回 (内容, 状态码, 响应头) 或 (内容, 状态码) 或 (内容, 响应头)。
return "Hello", 401: 设置 HTTP 状态码(如 401 Unauthorized)。
用途: 可用于反爬策略(数据正常返回,但状态码设置为错误)。
Response 对象:
创建:
make_response(内容): 将内容包装成 Response 对象。
直接实例化 Response: from flask import Response; Response(内容, status=状态码, headers=字典)。
作用: 当你需要操作响应头、设置 Cookie、进行重定向等高级操作时,必须使用 Response 对象。
底层: Flask 的 Response 对象是 werkzeug.wrappers.response.Response 的子类,并继承了多种混入类(Mixins),提供了丰富的功能(如 ETags, Streams, Authentication 等)。
3. 特殊响应类型:
重定向 (redirect):
功能: 将用户请求重定向到另一个 URL。
用法: from flask import redirect; return redirect(url_for('目标视图函数'))。
状态码: 默认返回 302 Found 状态码。
底层: redirect() 最终也返回一个 Response 对象。
终止执行 (abort):
功能: 立即停止请求处理,并返回指定的 HTTP 状态码错误页面。
用法: from flask import abort; abort(404)。
用途: 常用于权限验证失败、资源未找到等场景。
JSON 响应:
jsonify():
用法: from flask import jsonify; return jsonify(字典)。
功能: 将 Python 字典或列表序列化为 JSON 字符串,并自动设置 Content-Type: application/json。
推荐使用: 最佳实践,处理 JSON 响应的首选。
json.dumps() (原生 Python json 模块):
用法: import json; return json.dumps(字典)。
功能: 仅将数据序列化为 JSON 字符串,但不会自动设置 Content-Type 为 application/json。默认 Content-Type 仍为 text/html。
需手动设置: 若使用此方法,通常需要结合 Response 对象手动设置 Content-Type。
三、蓝图拆分(模块化)
1. 问题背景:
将所有路由和视图函数写在单个文件中(如 app.py 或 manager.py)会导致代码量庞大、难以维护和多人协作。
循环引用问题: 当尝试将路由拆分到单独的文件(如 views.py)时,如果 views.py 需要导入 app 对象进行路由注册 (app.route()),而主文件又需要导入 views.py 来加载路由,就会形成循环导入,导致程序崩溃。
2. 解决方案:蓝图 (Blueprint)
概念: 蓝图是 Flask 应用程序的模块化方式,它允许你定义路由、视图函数、模板文件夹、静态文件等,而无需直接关联到应用程序对象。
核心思想: 蓝图是应用程序的“待注册”部分,它在被注册到主应用之前是独立的。
使用步骤:
安装: pip install Flask-Blueprint (通常无需单独安装,Flask 内置)。
初始化蓝图:
from flask import Blueprint
# name: 蓝图名称,import_name: 当前模块的名称 (通常为 __name__)
my_blueprint = Blueprint('first_blueprint', __name__)
蓝图注册路由: 将 app.route() 替换为 my_blueprint.route()。
@my_blueprint.route('/hello')
def hello():
return "Hello from Blueprint!"
在主应用中注册蓝图: 在主应用文件中(如 manager.py),导入蓝图对象并将其注册到应用程序实例上。
from flask import Flask
from .views import my_blueprint # 从 views.py 导入蓝图实例
app = Flask(__name__)
app.register_blueprint(my_blueprint) # 注册蓝图
优势:
解决循环引用: views.py 不再直接导入 app 对象,而是使用独立的 Blueprint 对象注册路由。
模块化: 将应用逻辑拆分为更小的、可管理的模块,提高代码可读性、可维护性。
可复用性: 蓝图可以被不同的 Flask 应用或同一应用的多个部分注册使用。
URL 前缀: 注册蓝图时可以指定 URL 前缀,实现路由的命名空间隔离。
总结: 蓝图是 Flask 结构化大型应用的基石,通过它,我们可以实现类似 Django 的 MTV 分离,使项目结构更清晰,更易于开发和扩展。























暂无评论内容