路由

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)

 

 

posted @ 2023-04-13 21:35  www.pu  Views(43)  Comments(0Edit  收藏  举报