flask中添加路由的方式
在Flask中,添加路由有两种方式:(一般情况下都是用第一种方式)
方式一:常见的装饰器模式
@app.route("/") def index(): return "Hello World"
方式二:通过阅读装饰器模式添加路由的源码发现
def route(self, rule, **options):
"""A decorator that is used to register a view function for a
given URL rule. This does the same thing as :meth:`add_url_rule`
but is intended for decorator usage::
@app.route('/')
def index():
return 'Hello World'
For more information refer to :ref:`url-route-registrations`.
:param rule: the URL rule as string
:param endpoint: the endpoint for the registered URL rule. Flask
itself assumes the name of the view function as
endpoint
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object. A change
to Werkzeug is handling of method options. methods
is a list of methods this rule should be limited
to (``GET``, ``POST`` etc.). By default a rule
just listens for ``GET`` (and implicitly ``HEAD``).
Starting with Flask 0.6, ``OPTIONS`` is implicitly
added and handled by the standard request handling.
"""
def decorator(f):
endpoint = options.pop("endpoint", None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator
是通过self.add_url_rule这个方式建立起rule与视图函数的对应关系的,所以可以这样添加
def home(): return "Hello, home!" app.add_url_rule("/home", endpoint=None, view_func=home)
endpoint:给rule起一个别名,相当于django path路由函数中的name。
如何使用通过别名(endpoint)找到rule呢?(如果不起别名,就默认为函数名)
@app.route("/", endpoint="index") def index(): return "Hello World" def home(): from flask import url_for r = url_for("index") # / print(r) return "Hello, home!"
路由转化器
如何通过路由传递参数呢?<转换器:参数名>
@app.route("/<int:uid>/", endpoint="index") def index(uid): return "Hello {}".format(uid)
Flask中常用的转化器:
| 转换器名称 | 描述 | | ---------- | ------------------------------------------------------- | | string | 默认类型,接受不带斜杠的任何文本 | | int | 接受正整数 | | float | 接受正浮点值 | | path | 接收`string`但也接受斜线 | | uuid | 接受UUID(通用唯一识别码)字符串 xxxx-xxxx-xxxxx-xxxxx |
例子:
from flask import Flask # 2. 初始化web应用程序的实例对象 app = Flask(__name__) # 开启debug模式 app.config["DEBUG"] = True @app.route(rule="/", methods=["get", "post"]) def index(): return "<h1>hello flask1</h1>" """ 通过路由转换器来对路由参数显示格式转换和限制类型 """ @app.route("/goods/<float:cid>/<uuid:gid>") def goods(gid, cid): print(gid, type(gid)) print(cid, type(cid)) return f"显示cid={cid},gid={gid}的商品信息" if __name__ == '__main__': # 3. 运行flask提供的测试web服务器程序 app.run(host="0.0.0.0", port=5000)
上述中用到了路由转化器:float和uuid类型。
具体实现步骤为:
-
导入转换器基类BaseConverter:在 Flask 中,所有的路由的匹配规则都是使用转换器对象进行记录
-
自定义转换器:自定义类继承于转换器基类BaseConverter
-
添加转换器到默认的转换器字典DEFAULT_CONVERTERS中
-
使用自定义转换器实现自定义匹配规则
代码实现:
# 导入转化器基类 from werkzeug.routing.converters import BaseConverter # 自定义转换器 class RegexConverter(BaseConverter): def __init__(self, map, *args, **kwargs): super().__init__(map, *args, **kwargs) self.regex = args[0]
#
app.url_map.converters["re"] = RegexConverter
举例:
使用转换器去实现自定义匹配规则,当前此处定义的规则是:手机号码
# 1. 导入flask核心类 from flask import Flask # 2. 初始化web应用程序的实例对象 app = Flask(__name__) # 开启debug模式 app.config["DEBUG"] = True """ 自定义路由转换[在实际项目开发中,我们会单独准备一个python文件来保存转换器的定义代码] """ from werkzeug.routing.converters import BaseConverter class RegexConverter(BaseConverter): def __init__(self, map, *args, **kwargs): super().__init__(map, *args, **kwargs) self.regex = args[0] app.url_map.converters["re"] = RegexConverter @app.route("/sms/<re('1[3-9]\d{9}'):mobile>") def sms(mobile): return f"发送短信给手机号:{mobile}的用户" @app.route("/goods/<re('\d+'):id>") def goods(id): return f"显示商品id={id}的信息" if __name__ == '__main__': # 3. 运行flask提供的测试web服务器程序 app.run(host="0.0.0.0", port=5000)