• Flask_路由(二)


    一、路由规则设置说明

    flask框架使用route()装饰器配置路由。

    from flask import Flask
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def index():
        return "hello flask_url"

    路径分隔符

    在URL路径中,“/”被用作路径分隔符。当它被写在URL路径的开头时,则表明本路径是一个绝对路径。当它被写在路径中间时 ,它被用作隔离路径的层级。那么,当它被写在最后时,它的作用又是什么呢?

    # 路径分隔符
    @app.route("/hi1")
    def hi_1():
        return "hi1"
    
    
    @app.route("/hi2/")
    def hi_2():
        return "hi2"

    第1个路径没有“/”分隔符,它看上去更像是一个文件名;第2个路径的最后有“/”分隔符,它看上去更像是一个目录。两种方式对它们的访问效果可是有很大不同的:有“/”作为结尾的路径除了可以接受对其本身的访问,也可以接受相同路径前缀但不带“/”结尾的路径访问;而不带“/”结尾的路径样式则没有此效果。下面我们以表格的形式来呈现给大家看,看完你就会一目了然。

     

    请求方式限定

    使用 methods 参数指定可接受的请求方式,可以是多种。

    # 使用methods限定访问视图的方式。
    @app.route("/post_only", methods=["POST"])  # 只允许post方式访问视图
    def post_only():
        return "post_only"

    路由查找方式

    路由采用至上而下的查找方式。同一路由指向两个不同的函数,在匹配上第一个路由后就会停止查找。

    @app.route("/")
    def index():
        return "hello flask url"
    
    
    @app.route("/")
    def index2():
        return "hello flask url 2"

     但是相同路由若使用了不同的请求限定方式,则会匹配对应的请求方式

    # 当存在相同路径的路由时,根据请求方式区别视图
    @app.route("/hello", methods=["POST"])
    def hello1():
        return "hello1"
    
    
    @app.route("/hello", methods=["GET"])
    def hello2():
        return "hello2"

    一个视图可以配置多个路由

    @app.route("/route1")
    @app.route("/route2")
    def double_route():
        return "double_route"

     重定向

    在 redirect 方法中传入对应的url路径可实现重定向。

    from flask import redirect
    
    @app.route("/login")
    def login():
        url = "/hello"
        return redirect(url)

    url路径也可以使用url_for方法通过视图函数名获取。

    from flask import url_for
    
    @app.route("/hello", methods=["GET"])
    def hello2():
        return "hello2"
    
    # 重定向
    @app.route("/login")
    def login():
        # url = "/hello"
        # 使用url_for方法可以通过视图函数名找到对应的url路径
        # url = url_for("hello2", key1=value1, key2=value2)   # 若视图函数需要传入参数,则直接以键值的方式传入即可。
        url = url_for("hello2")
        return redirect(url)

    二、转换器

    转换器的本质是通过正则表达式匹配路由地址

    flask 系统自带的转换器如下:

    • string:UnicodeConverter, 接受任何不包含斜杠的文本,语法是 <string:参数名>。若不指定转换器类型,比如 <参数名>,flask默认使用该转换器。
    • any:AnyConverter, 接受给定的枚举值,语法是 <any(可选1,可选2...):参数名>,小括号列出匹配的枚举值,枚举值只能是字符串。
    • path:PathConverter, 类似 string ,但可以包含斜杠,语法是 <path:参数名>。
    • int:IntegerConverter, 接受正整数,语法是 <int:参数名>。
    • float:FloatConverter, 接受正浮点数,语法是 <float:参数名>。
    • uuid:UUIDConverter, 接受 UUID 字符串,语法是 <uuid:参数名>。

     当在路由中使用了转换器,若用户的输入满足转换器匹配规则,则响应200,反之,则响应404。

    # 匹配数字
    @app.route("/call/tel/1/<int:mobile>")
    def call_tel_1(mobile):
        return F"call tel {mobile}"

    自定义转换器

     flask的路由都是基于 werkzeug 函数库中的转换器实现的。

    当我们自定义转换器的时候的有以下步骤:

    1. 导入转换器基类(BaseConverter)
    2. 自定义转换器继承于转换器基类
    3. 添加转换器到默认的转换器字典中
    4. 使用自定义转换器实现自定义匹配规则
    # 自定义转换器
    # 1、导入转换器基类(BaseConverter)
    from werkzeug.routing import BaseConverter
    
    
    # 2、自定义转换器继承于转换器基类
    class MobileCheckConverter(BaseConverter):
    
        def __init__(self, url_map, mobile_regex):
            """
            :param url_map:获取flask的路由映射列表
            :param mobile_regex:获取第4步中的正则表达式
            """
            # 调用父类的初始化方法
            super().__init__(url_map)
    
            # 将第4步的正则规则保存到对象属性中,flask会使用这个属性进行路由匹配
            self.regex = mobile_regex   # self.regex 固定的属性,专门用来存放正则表达式
    
    
    # 3、将自定义的转换器添加到默认的转换器字典中
    app.url_map.converters["mobileCheck"] = MobileCheckConverter
    
    
    # 4、使用自定义转换器实现自定义匹配规则。
    # 括号中的正则表达式会传入到第2步自定义的转换器中。本例中为mobile_regex接收正则表达式。
    # 可以不使用括号传正则表达式,直接在第二步中的self.regex对象属性中直接定义正则表达式。
    @app.route("/call/tel/2/<mobileCheck(r'1[35]d{9}'):mobile>")     # 匹配13|15开头的11位手机号
    def call_tel_2(mobile):
        return F"call {mobile}"
    
    
    if __name__ == '__main__':
        # 通过url_map可以查看整个flask中的路由信息
        print(app.url_map)
        app.run()

     转换器中的to_python和to_url

    import time
    from flask import Flask, redirect, url_for
    
    class MobileConverter(BaseConverter):
        def __init__(self, url_map, regex):
            super().__init__(url_map)
            self.regex = regex
    
        def to_python(self, value):
            """
            在路由的正则匹配成功后调用,并将匹配到的值赋值给value,再调用视图函数将value传回给视图函数,可以利用该特性对值进行处理。
            :param value:
            :return:
            """
            print("to_python被调用", value)
            return value
    
        def to_url(self, value):
            """
            在to_python之后,调用视图函数之前调用。一般与url_for连用。
            若执行了to_python,则value值为to_python的return值。
            若使用了url_for,则value值为url_for传入的参数值,该值会传给重定向后的路由的to_python值
            :param value:
            :return:
            """
            print("to_url被调用", value)
            return value
    
    
    app.url_map.converters["getMobile"] = MobileConverter
    
    
    @app.route("/call/tel/3/<getMobile(r'd{11}'):mobile>")
    def call_tel_3(mobile):
        return mobile
    
    
    @app.route("/call/tel/4/<getMobile(r'd{3}'):mobile>")
    def call_tel_4(mobile):
        url = url_for("call_tel_3", mobile='15511112222')
        time.sleep(1)
        return redirect(url)

     附码:

    import time
    from flask import Flask, redirect, url_for
    from werkzeug.routing import BaseConverter
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def index():
        return "hello flask url"
    
    
    @app.route("/")
    def index2():
        return "hello flask url 2"
    
    
    # 路径分隔符
    @app.route("/hi1")
    def hi_1():
        return "hi1"
    
    
    @app.route("/hi2/")
    def hi_2():
        return "hi2"
    
    
    # 使用methods限定访问视图的方式。
    @app.route("/post_only", methods=["POST"])  # 只允许post方式访问视图
    def post_only():
        return "post_only"
    
    
    # 当存在相同路径的路由时,根据请求方式区别视图
    @app.route("/hello", methods=["POST"])
    def hello1():
        return "hello1"
    
    
    @app.route("/hello", methods=["GET"])
    def hello2():
        return "hello2"
    
    
    # 同一个视图可以配置多个路由
    @app.route("/route1")
    @app.route("/route2")
    def double_route():
        return "double_route"
    
    
    # 重定向
    @app.route("/login")
    def login():
        # url = "/hello"
        # 使用url_for函数可以通过视图函数名找到对应的url路径
        # url = url_for("hello2", key1=value1, key2=value2)   # 若视图函数需要传入参数,则直接以键值的方式传入即可。
        url = url_for("hello2")
        return redirect(url)
    
    
    # 转换器
    # 系统自带的转换
    #: the default converter mapping for the map.
    # DEFAULT_CONVERTERS = {
    #     "default": UnicodeConverter,
    #     "string": UnicodeConverter,   # 接受任何不包含斜杠的文本
    #     "any": AnyConverter,          # 接受给定的枚举值,语法是<any(可选1,可选2...):参数名>,小括号列出匹配的枚举值,枚举值只能是字符串。
    #     "path": PathConverter,        # 类似 string ,但可以包含斜杠
    #     "int": IntegerConverter,      # 接受正整数
    #     "float": FloatConverter,      # 接受正浮点数
    #     "uuid": UUIDConverter,        # 接受 UUID 字符串
    # }
    @app.route("/call/tel/1/<int:mobile>")
    def call_tel_1(mobile):
        return F"call tel {mobile}"
    
    
    # 自定义转换器
    # 1、导入转换器基类(BaseConverter)
    from werkzeug.routing import BaseConverter
    
    
    # 2、自定义转换器继承于转换器基类
    class MobileCheckConverter(BaseConverter):
    
        def __init__(self, url_map, mobile_regex):
            """
            :param url_map:获取flask的路由映射列表
            :param mobile_regex:获取第4步中的正则表达式
            """
            # 调用父类的初始化方法
            super().__init__(url_map)
    
            # 将第4步的正则规则保存到对象属性中,flask会使用这个属性进行路由匹配
            self.regex = mobile_regex   # self.regex 固定的属性,专门用来存放正则表达式
    
    
    # 3、将自定义的转换器添加到默认的转换器字典中
    app.url_map.converters["mobileCheck"] = MobileCheckConverter
    
    
    # 4、使用自定义转换器实现自定义匹配规则。
    # 括号中的正则表达式会传入到第2步自定义的转换器中。本例中为mobile_regex接收正则表达式。
    # 可以不使用括号传正则表达式,直接在第二步中的self.regex对象属性中直接定义正则表达式。
    @app.route("/call/tel/2/<mobileCheck(r'1[35]d{9}'):mobile>")     # 匹配13|15开头的11位手机号
    def call_tel_2(mobile):
        return F"call {mobile}"
    
    
    class MobileConverter(BaseConverter):
        def __init__(self, url_map, regex):
            super().__init__(url_map)
            self.regex = regex
    
        def to_python(self, value):
            """
            在路由的正则匹配成功后调用,并将匹配到的值赋值给value,再调用视图函数将value传回给视图函数,可以利用该特性对值进行处理。
            :param value:
            :return:
            """
            print("to_python被调用", value)
            return value
    
        def to_url(self, value):
            """
            在to_python之后,调用视图函数之前调用。一般与url_for连用。
            若执行了to_python,则value值为to_python的return值。
            若使用了url_for,则value值为url_for传入的参数值,该值会传给重定向后的路由的to_python值
            :param value:
            :return:
            """
            print("to_url被调用", value)
            return value
    
    
    app.url_map.converters["getMobile"] = MobileConverter
    
    
    @app.route("/call/tel/3/<getMobile(r'd{11}'):mobile>")
    def call_tel_3(mobile):
        return mobile
    
    
    @app.route("/call/tel/4/<getMobile(r'd{3}'):mobile>")
    def call_tel_4(mobile):
        url = url_for("call_tel_3", mobile='15511112222')
        time.sleep(1)
        return redirect(url)
    
    
    if __name__ == '__main__':
        # 通过url_map可以查看整个flask中的路由信息
        print(app.url_map)
        app.run()
  • 相关阅读:
    @slf4j 使用方法
    spark入门简单介绍
    spring boot 的简单实用和spring cloud 概念
    nginx与Tomcat
    python27+百度文字识别api
    python27+opencv2.4.10+pytesseract0.2.0图片识别
    学习vue的核心功能
    使用vscode +vue的初始环境搭建
    excel的vlookup,第一次用
    pyautogui键盘鼠标控制,python27
  • 原文地址:https://www.cnblogs.com/testlearn/p/14088841.html
Copyright © 2020-2023  润新知