本文共 3716 字,大约阅读时间需要 12 分钟。
在 Web 应用中,接口一般都是遵守 RESTful API 设计风格的,这种风格很优雅,而且对用户来说非常易于理解。
RESTful API 参考:
通过网络接口,程序员可以跳过 Web 的首页或导航页,直接访问到需要访问的页面,直接获取想要的数据。
在 Web 的后端,处理数据和返回数据的是视图函数,接口需要通过路由来映射到指定的视图函数上。
在 Flask 框架中,提供了 route() 装饰器来实现路由,使用 route() 装饰视图函数,在 route() 中传入该视图函数对应的 API 。使用装饰器的方式来实现路由非常方便,开发时可以集中精力来处理业务逻辑,加上装饰器就完成了接口和视图函数的映射关系。
一、Flask 中 route() 的基本使用
使用之前创建好的 FlaskProject 虚拟环境,项目文件名也叫 FlaskProject ,在 FlaskProject 目录下创建一个 flask_route.py 文件,编写后端的视图函数。
from flask import Flask, render_templateapp = Flask(__name__)@app.route('/index')def index(): return render_template('route_one.html')if __name__ == '__main__': app.run()
app 是实例化的 Flask APP 对象,通过 app.route() 来装饰视图函数。
在 route() 函数中,传入了参数 ‘/index’ ,说明当访问 /index 接口时,对应的后端视图函数是 index() 函数。访问 /index 获取到的响应内容就是 index() 函数返回的数据。
在上面的视图函数中返回了模板文件 route_one.html ,在 FlaskProject 目录下提前创建好了一个叫 templates 的模板文件夹,在模板文件夹中编写 route_one.html 模板文件。
Route Hello Jinja2 !
运行上面的 flask_route.py 程序,在前端访问 ,就可以访问到 route_one.html 页面。
二、在路由中传参
在上面的例子中, route() 中传入的 API 是硬编码“写死”的。
在很多场景下,需要用一个视图函数来动态返回数据,路由将 API 中的动态部分传递给视图函数,视图函数再根据参数动态地返回数据。
这种方式在 route() 中已经实现了,可以使用 route('<arg>') 的方式来传参。
在上面的 flask_route.py 中增加一个视图函数。修改如下:
from flask import Flask, render_templateapp = Flask(__name__)@app.route('/index')def index(): return render_template('route_one.html')@app.route('/phone/')def phone(num): return render_template('route_one.html', num=num)if __name__ == '__main__': app.run(debug=True)
在模板文件 route_one.html 中增加一个显示数据的标签。修改如下:
Route Hello Jinja2 !
Phone {
{ num }}
重新运行 flask_route.py ,在前端访问 /phone/<num> ,就可以将 num 从 url 传给路由,从路由传给视图函数,从视图函数传给模板文件,最终由模板文件展示在前端的页面上。
如访问 ,页面效果如下:
上面使用路由传递的参数是整数,但 route() 会默认当做 string 处理,默认会转换成字符串。上面只是用整数来作为例子,实际使用时,可以根据需求来指定传递的数据类型。
指定数据类型的方式为:route('/<数据类型:变量名>') ,如指定 num 参数是整数类型:route('/<int:num>') 。指定 int 后,route() 会将 url 中传过来的参数转换成 int 再传给视图函数。
三、正则匹配路由
在通过路由传递参数时,可以指定参数的数据类型,在 Flask 中,这种功能是通过转换器来实现的,转换器会按照定义的规则来转换或匹配参数。
Flask 自带的转换器有以下这些:
DEFAULT_CONVERTERS = { 'default': UnicodeConverter, 'string': UnicodeConverter, 'any': AnyConverter, 'path': PathConverter, 'int': IntegerConverter, 'float': FloatConverter, 'uuid': UUIDConverter,}
可以直接调用这些自带的转换器,也可以自定义转换器,如定义一个用正则来匹配的转换器,通过正则匹配路由。
正则可以对访问的路由进行匹配,满足规则才能访问成功。
自定义转换器的步骤为:
1. 导入 werkzeug 中的转换器基类,自定义的转换器需要继承 Flask 的 werkzeug 工具集中的转换器基类。
2. 自定义一个类继承于转换器基类,在类中重写转换器基类的 __init__ 方法,并定义正则转换器的第一个参数作为正则匹配规则。
3. 将正则转换器添加到默认的转换器字典 DEFAULT_CONVERTERS 中。
4. 在 route() 装饰器中使用正则转换器实现自定义匹配规则,在转换器后面传给正则转换器第一个参数,这个参数就是正则匹配规则。
继续在 flask_route.py 中添加代码,修改后如下:
from flask import Flask, render_templatefrom werkzeug.routing import BaseConverterapp = Flask(__name__)@app.route('/index')def index(): return render_template('route_one.html')@app.route('/phone/')def phone(num): return render_template('route_one.html', num=num)class RegexConverter(BaseConverter): def __init__(self, url_map, *args): super(RegexConverter, self).__init__(url_map) self.regex = args[0]app.url_map.converters['re'] = RegexConverter@app.route('/phones/ ')def phone_size(num): return render_template('route_one.html', num=num)if __name__ == '__main__': app.run(debug=True)
代码中先从 werkzeug.routing 导入了 BaseConverter,然后定义 RegexConverter 类继承 BaseConverter,url_map 参数是 Flask app 对象将自定义转换器添加到 DEFAULT_CONVERTERS 的方法,self.regex = args[0] 表示将这个类接收到的第一个参数作为正则规则。
使用 app.url_map.converters['re'] = RegexConverter 将自定义转换器注册到默认转换器字典中,在字典中 key 是 re ,value 是 RegexConverter,使用时通过 key 来调用。
使用 route() 装饰视图函数时,在 re() 内传入正则规则,如: route('/phones/<re("\w+"):num>') 表示 num 需要满足 \w+ 正则规则。
模板文件继续使用 route_one.html ,不做修改。
重新运行 flask_route.py ,在前端访问 /phones/<num> ,num 需要满足正则 \w+ ,才能请求到 phone_size() 视图函数。
如访问 ,页面效果如下:
转载地址:http://mgspz.baihongyu.com/