路由
1.路由的基本定义
什么是路由?
路由就是一种映射关系。是绑定应用程序(视图)和url地址的一种一对一的映射关系!我们在开发过程中,编写项目时所使用的路由往往是指代了框架/项目中用于完成路由功能的类,这个类一般就是路由类,简称路由。
flask中,url可以传递路由参数,有2种方式:
路由参数就是url路径的一部分。
路由和视图的名称必须全局唯一,不能出现重复,否则报错。
# 1. 导入flask核心类 from flask import Flask # 2. 初始化web应用程序的实例对象 app = Flask(__name__) # 开启debug模式 app.config["DEBUG"] = True # 路由方式一: # 参数1:rule设置当前视图的路由地址 # 惨呼2:methods,设置当前视图的HTTP请求方法,允许一个或多个方法,不区分大小写 @app.route(rule="/", methods=["get", "post"]) def index(): return "<h1>hello flask1</h1>" # # 路由方式二(来自于源码分析,一般不这样用,了解): # def order(): # return 'Order' # app.add_url_rule('/order',view_func=order) if __name__ == '__main__': # 3. 运行flask提供的测试web服务器程序 app.run(host="0.0.0.0", port=5000)
2.重定向
from flask import Flask, request, redirect, url_for, Response app = Flask(__name__) # 第一种: 跳转页面到站外+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @app.route("/jump") def jump(): """跳转页面到站外""" """ 301: 永久重定向,页面已经没有了,站点没有了,永久转移了。[域名映射-->域名解析] 302:临时重定向,一般验证失败、访问需要权限的页面进行登录跳转时,都是属于临时跳转。 """ # response = redirect("https://www.qq.com", 302) # print(response) # return response # 底层原理 response = Response("", 302, {"Location": "https://www.163.com"}) return response # 第二种:重定向到自己写的视图函数+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # 1)可以直接写对应的 url 路径 # 2)url_for反向生成url:指定视图名称,使用 url_for 生成指定视图函数所对应的 url(如果视图中指定了endpoint参数即函数别名,需要使用别名。视图名是默认的endpoint) @app.route("/user") def index(): if request.args.get("token"): return "个人中心" # 跳转页面到登录视图中 # redirect("url地址") # 控制页面跳转到任意路径下 # return redirect("/login") # 跳转页面到其他视图中 url = url_for("login") # url_for("视图名称"), 如果login中指定了endpoint参数即函数别名,需要使用别名。视图名是默认的endpoint print(app.url_map) # 路由列表,整个flask站点中所有的url地址和视图的映射关系都在这个属性里面 print(url) return redirect(url) @app.route("/login") def login(): return "登录视图" if __name__ == '__main__': app.run(host="0.0.0.0", port=5000, debug=True)
3.重定向到带有路径参数的视图函数
在 url_for 函数中传入参数 from flask import Flask, request, redirect, url_for, Response app = Flask(__name__) @app.route("/mobile/<int:mobile>") def sms(mobile): """发送短信""" return f"发送短信给{mobile}" @app.route("/info") def info(): # 跳转页面到一个具有路由参数的视图中 # return redirect("/sms/13012345678") url = url_for("sms", mobile="13012345677") print(url) # /sms/13012345677 return redirect(url) if __name__ == '__main__': app.run(host="0.0.0.0", port=5000, debug=True)
4.接收任意路由参数
# 1. 导入flask核心类 from flask import Flask # 2. 初始化web应用程序的实例对象 app = Flask(__name__) # 开启debug模式 app.config["DEBUG"] = True @app.route(rule="/", methods=["get", "post"]) def index(): return "<h1>hello flask1</h1>" """ 路由参数的传递 小括号圈住,里面写上参数变量名 在视图中即可通过参数列表按命名来接收 接收参数时,如果没有在设置路由中设置参数的类型,则默认参数类型为字符串类型 """ @app.route("/goods/<cid>/<gid>") def goods(gid, cid): print(gid, type(gid)) print(cid, type(cid)) return f"显示cid={cid},gid={gid}的商品信息" if __name__ == '__main__': # 3. 运行flask提供的测试web服务器程序 app.run(host="0.0.0.0", port=5000)
5.接收限定类型参数
限定路由参数的类型,flask系统自带转换器编写在werkzeug/routing/converters.py文件中。底部可以看到以下字典:
# converters用于对路由中的参数进行格式转换与类型限定的 DEFAULT_CONVERTERS: t.Mapping[str, t.Type[BaseConverter]] = { "default": UnicodeConverter, # 默认类型,也就是string "string": UnicodeConverter, # 字符串,不包含 / "any": AnyConverter, # 任意类型 "path": PathConverter, # 也是字符串,但是包含了 / "int": IntegerConverter, "float": FloatConverter, "uuid": UUIDConverter, }
系统自带的转换器具体使用方式在每种转换器的注释代码中有写,请留意每种转换器初始化的参数。
转换器名称 | 描述 |
---|---|
string | 默认类型,接受不带斜杠的任何文本 |
int | 接受正整数 |
float | 接受正浮点值 |
path | 接收string 但也接受斜线 |
uuid | 接受UUID(通用唯一识别码)字符串 xxxx-xxxx-xxxxx-xxxxx |
代码:
# 1. 导入flask核心类 from flask import Flask # 2. 初始化web应用程序的实例对象 app = Flask(__name__) # 开启debug模式 app.config["DEBUG"] = True @app.route(rule="/", methods=["get", "post"]) def index(): return "<h1>hello flask1</h1>" """ 通过路由转换器来对路由参数显示格式转换和限制类型 """ @app.route("/goods/<float:cid>/<uuid:gid>") def goods(gid, cid): print(gid, type(gid)) print(cid, type(cid)) return f"显示cid={cid},gid={gid}的商品信息" if __name__ == '__main__': # 3. 运行flask提供的测试web服务器程序 app.run(host="0.0.0.0", port=5000)
5.自定义路由参数转换器
也叫正则匹配路由参数.
在 web 开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要用到正则匹配,根据自己的规则去限定请求参数再进行访问
具体实现步骤为:
-
导入转换器基类BaseConverter:在 Flask 中,所有的路由的匹配规则都是使用转换器对象进行记录
-
自定义转换器:自定义类继承于转换器基类BaseConverter
-
添加转换器到默认的转换器字典DEFAULT_CONVERTERS中
-
使用自定义转换器实现自定义匹配规则
代码实现 manage.py:
运行测试:http://127.0.0.1:5000/sms/13012345671 ,如果访问的url不符合规则,会提示找不到页面
# 1. 导入flask核心类 from flask import Flask # 2. 初始化web应用程序的实例对象 app = Flask(__name__) # 开启debug模式 app.config["DEBUG"] = True """ 自定义路由转换[在实际项目开发中,我们会单独准备一个python文件来保存转换器的定义代码] """ # 第一步: 导入转换器基类 from werkzeug.routing.converters import BaseConverter # 第二步:自定义转换器 class RegexConverter(BaseConverter): def __init__(self, map, *args, **kwargs): super().__init__(map, *args, **kwargs) self.regex = args[0] def to_python(self, value): """ 路由匹配时,匹配成功后传递给视图函数中参数的值:源码默认返回value,即字符串,我们可以做出修改,返回int类型 :param value: :return: """ return int(value) def to_url(self, value): """ 使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数 :param value: :return: """ val = super().to_url(value) return val # return '我是自定义的url' # 第三步:添加转换器到默认的转换器字典中,并指定转换器使用时名字为: re app.url_map.converters["re"] = RegexConverter # 第四步:使用转换器去实现自定义匹配规则,当前此处定义的规则是:手机号码 @app.route("/sms/<re('1[3-9]\d{9}'):mobile>") def sms(mobile): v = url_for('index',nid='13012345671') # 利用url反向生成,查看to_url的效果 print(v) # /index/13012345671 | /index/我是自定义的url return f"发送短信给手机号:{mobile}的用户" @app.route("/goods/<re('\d+'):id>") def goods(id): return f"显示商品id={id}的信息" if __name__ == '__main__': # 3. 运行flask提供的测试web服务器程序 app.run(host="0.0.0.0", port=5000)