四、flask路由
4.1 源码分析
# 源码分析:
'''
self.add_url_rule(rule, endpoint, f, **options)
def add_url_rule(
self, # app对象
rule, # url路由
endpoint=None, # 路由别名
view_func=None, # 响应的函数名
provide_automatic_options=None,
**options
):
methods :['POST','GET'] —》控制请求方法,不传默认只能GET方法
'''
# @app.route的本质就在执行add_url_rule
# rule是路由,endpoint是路由别名,view_func是响应函数
# 如果endpoint不传就是响应的函数名
4.2 使用1:起别名
from flask import Flask , url_for, redirect
app = Flask(__name__)
def index():
print()
return "我是index"
# @app.route('/detail/<int:nid>',methods=['GET','POST'],endpoint='detail') # 典型写法
@app.route('/login')
def login():
print(url_for("index1")) # 走的别名,如果别名没有写,默认函数名
return redirect(url_for("index1")) # 走的别名,如果别名没有写,默认函数名
# url_for:
# 用endpoint获取路由要用url_for 在flask中导入,也就是反向解析
# 路由
app.add_url_rule('/', endpoint='index1', view_func=index)
# endpoint 别名
# view_func 响应的函数名
if __name__ == '__main__':
app.run()
4.3 使用2:有名分组
from flask import Flask , url_for, redirect
app = Flask(__name__)
# 必须接收分组名字一样的 nid
def index(nid):
print(nid)
return "我是index"
# 路由:有名分组
app.add_url_rule('/index/<string:nid>', endpoint='index1', view_func=index, methods=['POST','GET'])
app.add_url_rule('/index/<int:nid>', endpoint='index', view_func=index, methods=['POST','GET'])
# 浏览器:http://127.0.0.1:5000/index/asdfas
# string、int 规定接收的类型
if __name__ == '__main__':
app.run()
4.4 路由小总结
总结:
1 @app.route("/login") 的本质app.add_url_rule("/login",view_func=login),所以我们就可以用这两个方式来添加路由
2 路由的参数,
2.1 endpoint,做是反向解析,如果上面添加路由的时候,没有传递endpoint就是使用响应函数的函数名,反向解析用url_for(),做解析,这个url_for必须在flask里面导入
2.2 methods=["POST","GET"],该参数控制路由允许哪些请求方法访问,如果不传,默认只能GET方法
2.3 路由以及路由路由转化器。"/index/<int:nid>",<参数的类型:用哪个变量来接收>,响应函数中的形参的名字必须转化器中一致。
4.5 默认转化器
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
4.6 自定义转换器
#1 写类,继承BaseConverter
#2 注册:app.url_map.converters['regex'] = RegexConverter
# 3 使用:@app.route('/index/<regex("\d+"):nid>') 正则表达式会当作第二个参数传递到类中
from flask import Flask, views, url_for
from werkzeug.routing import BaseConverter
app = Flask(import_name=__name__)
# 1.写类
class RegexConverter(BaseConverter):
"""
自定义URL匹配正则表达式
"""
def __init__(self, map, regex):
super(RegexConverter, self).__init__(map)
self.regex = regex
def to_python(self, value):
"""
路由匹配时,匹配成功后传递给视图函数中参数的值
"""
return int(value)
def to_url(self, value):
"""
使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
"""
val = super(RegexConverter, self).to_url(value)
return val
# 2.注册:添加到flask中
app.url_map.converters['regex'] = RegexConverter
# 正则匹配处理结果,要交给to_python,to_python函数可以对匹配处理结果做处理
# 3.使用:
@app.route('/index/<regex("\d+"):nid>')
def index(nid):
print(url_for('index', nid='888'))
return 'Index'
if __name__ == '__main__':
app.run()
4.7 自定义转换器总结
1 导入from werkzeug.routing import BaseConverter
2 我写个继承BaseConverter。实现3个方法,def __init__ , def to_python , def to_url
3 将上面的类注册到app.url_map.converters['regex'] = RegexConverter中
4 然后就可以在路由转化器中使用3中的regex("传正则")
5 当路由被访问以后。regex("传正则")会匹配结果,把结果传递to_python,我们可以进行再次处理,to_python处理好的结果,会传递给响应函数的形参
6 当用url做反向解析的时候,传递给路由转化器的参数,会经过to_url,进行处理。处理以后,在拼接到路由。