Flask路由和蓝图
Flask路由和蓝图
路由定义
在Flask中,路由用于将HTTP请求与特定的Python函数相匹配。
通过定义路由,Flask应用程序可以响应URL的请求,执行相应的函数,然后将结果返回给用户。
Flask 提供了两种方式配置路由
- 方式1-装饰器方法
@app.route(uri, methods)
- 方法2-函数配置
add_url_rule
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
info = {
'message': "这是存在message变量中的信息"
}
return render_template('index.html', info=info)
# 使用第二种方式给index()视图函数配置路由
app.add_url_rule("/index",view_func=index)
if __name__ == '__main__':
app.run() # 运行程序
"/" 和 "/index" 都可以映射到 index() 视图函数上.
浏览器访问 127.0.0.1/index
查看路由信息
url_map对象
在Flask中,可以通过Flask实例对象app的url_map
属性来获取应用程序中定义的所有路由信息。还可以使用url_map对象的方法和属性来查看每个路由所属的蓝图、请求方法和端点等详细信息。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def route_map():
print(app.url_map)
return 'Hello, World!'
# 显示输出------------------------------------------------------
Map([<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/' (HEAD, OPTIONS, GET) -> index>])
map: 表示路由映射,容器列表
rule: 路径规则,存储了url的路径名、http请求⽅法、端点(视图函数名)
遍历路由信息
for rule in app.url_map.iter_rules():
print('name={} path={}'.format(rule.endpoint, rule.rule))
# name=static path=/static/<path:filename>
# name=index path=/
视图返回路由信息
@app.route('/')
def route_map():
"""
主视图,返回所有视图地址
"""
rules_iterator = app.url_map.iter_rules()
return json.dumps({rule.endpoint: rule.rule for rule in rules_iterator})
路径参数设置和获取
有很多请求我们URL地址后面会跟着参数,并且后端要提取到参数,比如:http://127.0.0.1:5000/center/1
这个URL地址后面有个1,可以代表我们要访问uid为1的个人信息。
Flask支持多种转换器,URL 路径中可以进行参数的传递,Flask 中 URL 参数的类型有:
- string:接收任何不包含斜杠的问题本
- int:接收正整数
- float:接收浮点数
- path:类似 string,但可以包含斜杠
- uuid:接收 uuid 字符串
@app.route('/page/<int:page_number>')
def list(page_number):
return '这是第{}页用户'.format(page_number)
浏览器访问 http://127.0.0.1:5000/page/100
@app.route('/page/')
@app.route('/page/<int:page_number>')
def list(page_number=1):
return '这是第{}页用户'.format(page_number)
add_url_rule的参数
add_url_rule(rule,endpoint=None,view_func=None,provide_automatic_options=None, **options)
rule: URL规则
view_func: 路由视图函数名称
defaults = None 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}为函数提供参数
endpoint = None 名称,用于反向生成URL,即: url_for('名称')
methods = None 允许的请求方式,如:["GET", "POST"]
#对URL最后的 / 符号是否严格要求
strict_slashes = None
'''
@app.route('/index', strict_slashes=False)
#访问http://www.xx.com/index/ 或http://www.xx.com/index均可
@app.route('/index', strict_slashes=True)
#仅访问http://www.xx.com/index
'''
#重定向到指定地址
redirect_to = None,
'''
@app.route('/index/<int:nid>', redirect_to='/home/<nid>')
'''
关于endpoint
endpoint相当于实际url的一个别名,在浏览器输入地址时,需要在flask后台寻找相应的路由函数(从而查找相应的资源),而在查找的过程中,不是直接用物理地址来进行硬编码的,而是通过映射成endpoint来查找。也就是说,开发者定义的每一个路由地址都有一个注册的endpoint与之对应。在客户端输入地址在后台查询资源的时候,通过这个endpoint来查找相应的路由函数
执行流程分析
from flask import Flask
app = Flask(__name__)
# (3)路由系统的本质
# @app.route('/index', methods=['GET']) 本质上是一个装饰器
# 执行时 ---> index = @app.route('/index', methods=['GET'])(index)
@app.route('/index', methods=['GET'])
def index():
return 'hello world'
if __name__ == '__main__':
app.run()
- 执行
@app.route('/index', methods=['GET'])
- 本质上执行了
index = @app.route('/index', methods=['GET'])(index)
- 触发了 route 方法中的
decorator
def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
def decorator(f: T_route) -> T_route:
endpoint = options.pop("endpoint", None)
self.add_url_rule(rule, endpoint, f, **options)
return f # f 是视图函数 ,在这里并没有对视图函数进行额外的处理,只是加了一些参数
return decorator
- f 是视图函数 ,在这里并没有对视图函数进行额外的处理,只是加了一些参数
endpoint = options.pop("endpoint", None)
self.add_url_rule(rule, endpoint, f, **options)
- 视图函数执行
@app.route('/index', methods=['GET'])
- endpoint 携带在 route 内
- 从 options 中弹出 endpoint ,有则弹出,无则 None
- 核心
self.add_url_rule(rule, endpoint, f, **options)
- self 就是 app 对象
app.add_url_rule('路由地址', '路由的别名', '视图函数', '其他参数')
from flask import Flask
app = Flask(__name__)
# @app.route('/index', methods=['GET'])
def index():
return 'hello world'
# 自定义注册路由和视图
app.add_url_rule('/index', 'index', index, '其他参数')
if __name__ == '__main__':
app.run()
重定向
redirect
函数用于重定向。 url_for
参数是视图函数函数的名字,它会根据视图函数的名字找到装饰次视图的路由。
from flask import Flask
from flask import abort, redirect, url_for
app = Flask(__name__)
@app.route('/') # 代表首页
def index(): # 视图函数
return 'my index !' # 返回内容
@app.route('/center') # 代表个人中心页
def center(): # 视图函数
return 'my flask!' # 返回内容
@app.route('/login') # 代表登录
def login(): # 视图函数
return redirect(url_for('index'))
if __name__ == '__main__':
# 0.0.0.0代表任何能代表这台机器的地址都可以访问
app.run(host='0.0.0.0', port=5000) # 运行程序
蓝图概述
蓝图是一种组织Flask程序路由的方式,它可以帮助我们更好地组织代码,使得应用程序更加模块化、易于管理。通过使用蓝图,我们可以将应用程序划分成多个模块,在每个模块内部定义自己的路由,然后将这些模块注册到主应用程序中。
蓝图实际可理解为是一个存储一组视图方法的容器对象,其具有如下特点:
-
一个应用可以有多个Blueprint
-
可将一个Blueprint注册到任何一个未使用的URL下,如"/users"
-
Blueprint可以单独具有自己的模板、静态文件或者其他通用操作方法,它并不是必须要实现应用的视图和函数的
基本使用
-
创建蓝图对象,可创建一个新的包,如user,然后在其中创建蓝图
-
在这个蓝图对象上进行操作,注册路由,指定静态文件夹,注册模板过滤器等
-
在应用对象上注册这个蓝图对象
from flask import Flask, Blueprint
# 创建Flask应用程序实例
app = Flask(__name__)
# 1.创建一个蓝图对象,设置静态目录的路由
user_bp = Blueprint('user', __name__,static_folder='static_users')
# 2.在这个蓝图对象上进行:注册路由,指定静态文件夹,注册模版过滤器
@user_bp.route('/')
def user_info():
return 'user_info'
# 3.在应用对象上注册这个蓝图对象
app.register_blueprint(user_bp)
if __name__ == '__main__':
app.run()
def __init__(self, name, import_name, static_folder=None,
static_url_path=None, template_folder=None,
url_prefix=None, subdomain=None, url_defaults=None,
root_path=None):
name: 即路由的别名,在子模块中定义的蓝图要想通过在主模块中注册使用
import_name:表示模块的系统变量,用来区别是子模块还是主模块
url_prefix: 路由前缀
static_folder: 静态文件夹 指明静态文件的搜寻路径
template_folder:模板文件夹 指名模板文件搜索路径
url_defaults: 默认的路由路径别名,保存是字典形式,含有两个参数的元组形式
在应用中注册蓝图时使用url_prefix
参数指定
app.register_blueprint(user_bp, url_prefix='/user')
app.register_blueprint(goods_bp, url_prefix='/goods')
内部静态文件
和应用对象不同,蓝图对象创建时不会默认注册静态目录的路由。需要我们在 创建时指定 static_folder 参数
admin = Blueprint("admin",__name__,static_folder='static_admin')
app.register_blueprint(admin,url_prefix='/admin')
现在就可以使用/admin/static_admin/<filename>
访问static_admin
目录下的静态文件
内部模板目录
同样的蓝图对象默认的模板目录为系统的模版目录,可以在创建蓝图对象时使用 template_folder 关键字参数设置模板目录
admin = Blueprint('admin',__name__,template_folder='my_templates')
参考资料
https://juejin.cn/post/6844903826667880456?from=search-suggest
https://juejin.cn/post/6844903834750304269?from=search-suggest