掘金 后端 ( ) • 2024-06-25 17:34

theme: awesome-green highlight: atelier-cave-light

本章介绍 get 请求的简单使用和复杂使用,并包括 get 参数类型定义的实现。

如果对下面的开头内容,有些不明白的,请先看看上一章内容。 上一章内容:Flask系列分享:Flask的启动

1. 启动 Flask

import os
from flask import Flask

# 创建 Flask 应用
app = Flask(os.getcwd())

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=9999, debug=True)

2. get 请求

2.1 get 无参请求

    ```
        使用 route() 装饰器来告诉 Flask 触发函数的URL。
        
        route 参数介绍:
            第一个参数: 必须是字符串的路由地址,如: /a, /a/b, a, /,等。不能不写,或者写入""
                       (空字符串和空白字符串),这种写法都会导致报错。
            methods: 是一规定请求格式的列表字符串,用来确定当前路由是 get 请求,还是 post请求,
                     或者put和delete等请求。既然是一个列表字符串,那么就能写入多个请求格式。
                     
            如果 route 函数的第一个参数字符串为 "/" ,同时没有设置 methods 参数时,默认请求
        规则为 get。当在浏览器访问 http://127.0.0.1:9999 时触发 index 函数,页面会显示 
        "请求成功" 字段。
    ```
    @app.route("/")
    def index():
        return "请求成功"

2.2 get 无参请求的另外两种实现

  1. app.add_url_rule 路由动态映射指定函数。
  2. @app.get 直接使用 get 请求。

其实,不管是 @app.route 装饰器函数,还是 @app.get 装饰器函数呢,Flaks 底层最终都是调用 app.add_url_rule 去实现路由地址和执行函数进行映射的。

    ```
         app.add_url_rule的实现
    ```
    def index():
        return "请求成功"
    
    ```
        参数1:     与 route 装饰器函数传入的参数规则一致
        methods:   与 route 装饰器函数传入的参数规则一致
        view_func: 传入路由地址需要执行的函数
    ```
    app.add_url_rule("/", view_func=index)
    
    ```
        @app.get 的实现
    ```
    @app.get("/")
    def index1():
        return "请求成功"
    
    

2.3 get 有参请求

    ```
            如果要在 route 装饰器函数中需要指定参数名称的话,那么执行的函数中也要写入相同的变量名,
        否则 Flask 底层校验不通过,会报错。如果有多个,函数中就要一一对应写上。
        
            当然在 index函数中写入 **kwargs。表示 index 函数可以接收多个不定键值对参数,也就是一个
        不定的 dict 类型参数。这种写法,Flask 底层也是能校验通过的。
    ```
    @app.route("/<id>")
    def index(id):
        return f"请求成功,id: {id}"
        
    @app.get("/<name>/<age>")
    def index1(id):
        return f"请求成功,姓名:{args['name']}, 年龄:{args['age']}"
     
     def index2(id)
         return f"请求成功,姓名:{args['name']}, 年龄:{args['age']}"
         
    app.add_url_rule("/<name>/<age>", view_func=index2)
    

image.png

2.4 get 有参请求之参数类型定义

Flaks 中的 get 路由请求中呢,如果想要给某些参数指定简单类型,Flask 也是能满足的。但是目前只支持以下七种类型:

  1. default:默认转换器。如果没有显式指定类型转换器,Flask会使用UnicodeConverter,它将URL中的参数当作普通的字符串处理。
  2. string: 字符串转换器。与默认转换器相同,将URL参数作为普通字符串处理。
  3. int: 整数转换器。将URL参数转换为整数类型,如果参数不是有效的整数,则会导致路由匹配失败。
  4. float: 浮点数转换器。将URL参数转换为浮点数类型。
  5. uuid: UUID转换器。将URL参数转换为UUID对象,UUID是一种通用唯一识别码格式,用于标识唯一对象。
  6. any: 任意值转换器。允许参数匹配任何值。
  7. path: - - 路径转换器。类似于字符串转换器,但它允许斜杠(/)作为参数的一部分。这意味着它可以匹配更复杂的路径参数。

下面,我们来一一实现下这些类型

    ```
    1. default
        顾名思义默认类型,也就是说参数不设置类型,就是默认类型,而 Flask 默认类型又指向的是 string 类
    型。所以写 default 和不写,参数类型都默认是 string 类型。如上面 2.3 get 有参请求那样的写法。
    ```
    @app.route("/<id>")
    def index(id):
        return f"请求成功,id: {id}"
        
    ```
    2. string 
        上面已经说了,定义为 default 也是转为 string 类型。所以定义 string 类型与不写,都是一样的,
    现在我们来实现看看。
    ```
    @app.get('/<string:name>')
    def index(name):
        return f"请求成功,姓名:{name}"

image.png

    ```
    3. int
        定义参数为整数类型,并且必须是正整数,才能正常访问。
        其实在地址栏中输入的都是字符串,而定义了 id 为 int 类型时, Flask 在接收请求时,会去将指定参数
    尝试转为指定类型,如果转义不成功,则会报 404 错误。
    ```
    @app.get("/<int:id>"):
    def index(id):
        return f"请求成功, id: {id}, 类型为: {type(id)}"

image.png

image.png

image.png 只要传递的参数,无法正常转为指定的类型,就都直接返回 404。

    ```
    4. float
        浮点类型,一般是指定某个参数需要精确到小数,就用浮点类型。如果不能正确转义,也是返回 404 错误。
        如果输入的是个整数,也要写成浮点数,比如18,就要写成18.0,这样才符合浮点数规则。
    ```
    @app.get(/<float:id>)
    def index(id):
        return f"请求成功, id: {id}"

image.png

    ```
    5. uuid
        要求传递过来的参数必须是个 uuid 类型的值,Flask 校验失败,就会返回 404 错误请求。
        通常给某个订单或者某个资源设置唯一 id 时,就需要使用 uuid 来定义。
        不过一般都是后端生成处理了,很少需要传入 uuid 。
    ```
    @app.get("/<uuid:id>")
    def index(id):
        return f"请求成功, id: {id}"

image.png

    ```
    6. any
        `any` 类型路径参数的主要用法是限制路径参数的值在一个预定义的选项集合中。通过结合其他功能
    (如查询字符串参数、多 `any` 参数和动态生成选项集合),你可以实现更加灵活和复杂的路由控制。
    虽然 `any` 本身的用法相对简单,但通过巧妙组合,可以满足更多样化的需求。
    ```
    
    roleList = ["user", "admin", "guest"]
    actionList = ["view", "edit"]
    
    # 第一种写法
    # @app.get("/<any(user, admin, guest):role>/<any(view, edit):action>")
    
    # 第二种写法 动态生成 `any` 类型参数的选项集合
    @app.route(f"/<any({','.join(roleList)}):role>/<any({','.join(actionList)}):action>")
    def index(role, action):
        return f"请求成功, roue: {role}, action: {action}"

上面两种写法呢,不管是写死的,还是动态生成的。路由组合的参数值,都必须要满足 any 括号中声明的值。Flask 将逐个进行匹配,只要有一个没匹配成功。 Flask 就会返回 404 错误响应。 例如:

http://localhost:9999/user/view
http://localhost:9999/user/edit
http://localhost:9999/admin/view
http://localhost:9999/admin/edit
http://localhost:9999/guest/view
http://localhost:9999/guest/edit

这六个路由地址都是由 roleListactionList 列表组合的路由,方能访问成功。 如果,roleListactionList 列表其中有个为空列表,那怎么传参呢?

测试证明,如果有两个 any 类型的参数,首个 any 类型的值不能为空,否则 Flask 匹配规则无法通过。

如果第一个 any 类型的值不为空,而第二个为空的话,那么在第一个参数的后面跟上/(斜杠)也能正常访问。这是因为第一个 any 类型的值能正确匹配上,那么就说明这是个有效的路由,后面的哪怕为空,也能正确访问此路由。

可以看看下面代码截图和访问结果片段:

image.png

image.png

image.png

image.png 从上面几张图可以看出,只要第一个路由参数不为空,并且匹配成功,那么就能正常访问。

    ```
    7. path
    动态匹配路由路径,将匹配的路由路径赋值给指定的参数。
    ```
    @app.get("/files/<path:file_path>")
    def index(file_path):
        return f"请求成功, 匹配的路由地址为: {file_path}"

可以看到,只要是 /files/ 后面的内容都能匹配到,并赋值给 file_path。 image.png

反思,如果把 /files 去除呢?

image.png

image.png

可以看到,path 类型,就会从根路径开始匹配,并赋值给 file_path。也可以理解为这是一个万能 get 请求了,前提是,必须最起码要写一个路由地址,这样才能正确访问。否则就是 404。

image.png

path 类型路径参数非常适用于以下场景:

  1. 文件路径:当你需要处理文件路径时,使用 path 类型可以捕获完整的文件路径,包括子目录。
  2. 动态URL:在需要捕获URL片段或其他包含斜杠的参数时,path 类型路径参数是非常有用的。

通过使用 path 类型路径参数,你可以处理包含斜杠的复杂路径,从而增强 Flask 应用的灵活性和功能性。

2.5 get 请求之 request 获取参数值

from flask import request

@app.get("/")
def index():
    args = dict(request.args)
    result = "请求成功"
    for k, v in args.items():
        result += f"{k}: {v}, "
    return result[:-2]

image.png 这种使用个 Flask 的 request 类来获取地址栏传过来的参数,不论多少个,都能正常获取到。但是写法稍有不同,是以?name=小明&age=18这种格式传参。

目前暂时介绍这么多 Flask 中 get 请求的使用,后期如果想到或者碰到其他使用方案,再做补充。