天天看点

【Flask】路由装饰器、路径传参、自定义路由转换器

1.路由

路由就是根据请求方式和url确定由哪个视图函数进行处理,不像Django通过路由列表,Flask是通过装饰器的方式

@app.route()

指定视图函数以及支持的请求方式,该方法可以传入url和methods

from flask import Flask

app = Flask(__name__)

@app.route(rule="/index", methods=["get", "post"])  # 指定路径,支持的请求方式(可使用默认的)
def index():
    return "index"

if __name__ == '__main__':
    print(app.url_map)  # 打印所有的路由规则
    app.run(debug=True)
           

app.route()方法主要有两个参数,rule 是必须以“ / ”开头的路径,methods 是一个list或tuple,限定支持的请求方式

另外,可以通过

app.url_map

属性获取所有的路由规则

2.路径传参

传参的方式有多种,比如说请求头、表单、非表单等、查询字符串等,当然还有路径传参,如果遇到路径传参,我们就需要把它提取出来

格式是:

/xx/<路由变量>

from flask import Flask

app = Flask(__name__)

@app.route(rule="/user_id/<uid>")  # 用<>指定路径变量名为uid
def index(uid):
    return uid

if __name__ == '__main__':
    app.run(debug=True)

           
2.1 路由转换器

直接使用<>指定的变量是str类型的,如果需要特定的类型,可以使用类型转换器。

其实每个类型转换器都是一个类,继承于BaseConverter类,该类位置是werkzeug.routing.BaseConverter

以下是默认的类型转换器,位于werkzeug.routing的DEFAULT_CONVERTERS列表中

DEFAULT_CONVERTERS = {
    "default": UnicodeConverter,
    "string": UnicodeConverter,
    "any": AnyConverter,
    "path": PathConverter,
    "int": IntegerConverter,
    "float": FloatConverter,
    "uuid": UUIDConverter,
}

           

比如说,我们需要把路径参数转换成一个int类型

from flask import Flask

app = Flask(__name__)

@app.route(rule="/user_id/<int:uid>")  # 将参数uid转换成int类型
def index(uid):
    print(type(uid))
    return str(uid)

if __name__ == '__main__':
    app.run(debug=True)
           
2.2 自定义路由转换器

因为已有的转换器不能满足我们的需求,比如说,想要一个手机号或邮箱类型的转换器,我们就得自己写一个了。思路很简单,就是继承

BaseConverter

这个类,然后重写

regex

属性实现正则匹配,再把自定义的类添加到

app.url_map.converters

这个字典里即可

from flask import Flask
from werkzeug.routing import BaseConverter

app = Flask(__name__)

# 自定义类型转换器
class MobileConverter(BaseConverter):
    regex = "1[3-9]\d{9}$"  # 匹配规则,不要以^开头

app.url_map.converters["mobile"] = MobileConverter  # 添加到转换器列表

@app.route(rule="/user/<mobile:mobile>")  # 将参数uid转换成mobile类型
def index(mobile):
    print(type(mobile))
    return str(mobile)

if __name__ == '__main__':
    app.run(debug=True)