flask框架之路由和URL
1.路由和URL
1.1 路由
@app.route("/index") def view_func(): #视图函数 return "hello 李四"
在程序中获取路由信息
在应用中的url_map属性中保存着整个Flask应用的路由映射信息,可以通过读取这个属性获取路由信息
print(app.url_map)
如果想在程序中遍历路由信息,可以采取如下方式
for rule in app.url_map.iter_rules(): print(f"name={rule.endpoint} path={rule.rule}")
需求
通过访问/地址,以json的方式返回应用内的所有路由信息
实现
1 from flask import Flask, json 2 3 app = Flask(__name__) 4 5 6 @app.route('/') 7 def hello_world(): 8 # rules就是整个web项目的路由列表 9 rules = app.url_map.iter_rules() 10 # for rule in rules: 11 # print(f"视图函数:{rule.endpoint},url地址:{rule.rule}") 12 13 return json.dumps({rule.endpoint: rule.rule for rule in rules}) 14 15 16 @app.route('/test1') 17 def test1(): 18 return '' 19 20 21 @app.route('/test2') 22 def test2(): 23 return '' 24 25 26 if __name__ == '__main__': 27 app.run(host='0.0.0.0')
1.2 动态路由(URL路径参数)
例如,有一个请求访问的接口地址为users/123,其中123实际上为具体的请求参数,表明请求123号用户的信息,此时如何从url中提取出123的数据
Flask不同于django直接在定义路由时编写正则表达式的方式,而是采用转换器语法:
1 from flask import Flask 2 3 app = Flask(__name__) 4 5 @app.route('/') 6 def hello_world(): 7 return 'hello world!' 8 9 10 @app.route('/user/<user_id>') 11 def users(user_id): 12 print(type(user_id)) 13 return f"当前访问的用户是 :用户{user_id}" 14 15 16 if __name__ == '__main__': 17 app.run(host="0.0.0.0")
此处的<>即是转换器,默认为字符串类型,即该位置的数据以字符串格式进行匹配、平以字符串为数据类型,id为参数名传入视图
Flask也提供其他类型的转换器
1 DEFAULT_CONVERTERS={ 2 'default': UnicodeConverter, 3 'string': UnicodeConverter, 4 'any': AnyConverter, 5 'path': PathConverter, 6 'int': IntegerConverter, 7 'float': FloatConverter, 8 'uuid': UUIDConverter 9 }
将上面的例子以整型匹配数据,可以如下使用:
1 from flask import Flask 2 3 app = Flask(__name__) 4 5 @app.route('/') 6 def hello_world(): 7 return 'hello world!' 8 9 10 @app.route('/user/<int(min=1):id>') 11 def users(id): 12 print(type(id)) 13 return f"当前访问的用户是 :用户{id}" 14 15 16 if __name__ == '__main__': 17 app.run(host="0.0.0.0")
自定义转换器
如果遇到需要匹配提取 /sms_codes/18522304756 中的手机号数据,Flask内置转换器就无法满足需求,此时需要自定义转换器
定义方法
自定义转换器主要做3步
1.创建转换器类,保存匹配时的正则表达式
1 from flask import Flask 2 from werkzeug.routing import BaseConverter 3 4 '''我们自定义的转换器必须要继承当前的BaseConverter父类''' 5 6 7 class MobileConverter(BaseConverter): 8 # 定义一个匹配手机号码的正则表达式 9 regex = r'1[3-9]\d{9}' 10 11 12 app = Flask(__name__) 13 14 # 将自定义的转换器添加到转换器列表中 15 app.url_map.converters['phone'] = MobileConverter # phone是转换器的名字 16 17 18 @app.route('/') 19 def hello_world(): 20 return 'Hello World' 21 22 23 @app.route('/phone/<phone:mob_num>') 24 def phone_number(mob_num): 25 return f'当前您访问的手机号码是:{mob_num}' 26 27 28 if __name__ == '__main__': 29 app.run(host='0.0.0.0')
1.3 url_for函数
一般我们通过一个URL就可以执行到某一个函数,如果反过来,我们知道一个函数,怎么去获得这个URL呢?url_for函数就可以帮我们实现这个功能
url_for():函数接收两个及以上的参数,他接收函数名作为第一个参数,接收对应URL规则的命名参数,如果还出现其他的参数,则会添加到URL的后面作为查询参数
比如:
1 from flask import Flask, url_for, redirect 2 3 app = Flask(__name__) 4 5 6 @app.route('/') 7 def hello_world(): 8 print(url_for('login', user_name='zhangsan')) 9 print(url_for('login', user_name='zhangsan', page=2)) 10 # return url_for('login',user_name='zhangsan') 11 return redirect(url_for('login', user_name='zhangsan')) 12 13 14 @app.route('/login/<user_name>') 15 def login(user_name): 16 return f'当前登录的用户是:{user_name}' 17 18 19 if __name__ == '__main__': 20 app.run(host='0.0.0.0')
注意:url_for()函数还会转义一些特殊字符和unicode字符串。比如:中文或者/