博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python Flask 中的路由
阅读量:561 次
发布时间:2019-03-09

本文共 3716 字,大约阅读时间需要 12 分钟。

Python Flask 中的路由

在 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/

你可能感兴趣的文章