路由简介
在flask程序中使用路由,我们称之为注册路由,是使用程序实例提供的app.route()装饰器来注册路由。
@app.route('/student_list/')
def student_list():
return 'students'
路由的本质及参数
from flask import Flask, url_for, redirect
app = Flask(__name__)
def index(nid):
print(nid, type(nid))
return 'ojbk'
# 指定类型为int或者string类型
app.add_url_rule('/index/<int:nid>', view_func=index, endpoint='index1', methods=['post', 'get'])
# app.route的本质就在执行add_url_rule这个中的rule是路由,endpoint是路由别名,view_func是响应函数
# app.add_url_rule('/index/<int:nid>', view_func=index, methods=['post', 'get'])
@app.route('/login', methods=['get', 'post'])
def login():
# 用endpoint取路由要用url_for 在flask中导入,也就是反向解析
print(url_for("index1"))
return redirect(url_for("index1")) # url_for通过路由的别名反向解析出来路由的url
# 路由参数;methods,可以控制该方法能有哪些请求方式可以访问
app.add_url_rule("/index", endpoint="index1", view_func=index, methods=["POST", "GET"])
# 路由参数:有名分组,app.add_url_rule("/index/<int:nid>"响应函数必须用nid来接收
if __name__ == '__main__':
app.run()
'''
总结:
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>",<参数的类型:用哪个变量来接收>,响应函数中的形参的名字必须转化器中一致。
'''
动态路由传参
http://127.0.0.1:5000/student_list/2/
在path中有可变的部分,达到了传参的目的,我们称之为动态路由传参
@app.route('/student_list/<student_id>/')
def student_list(student_id):
return '学生{}号的信息'.format(student_id)
动态路由的过滤
可以对参数限定数据类型,比如限定为student_id必须为整数类型
http://127.0.0.1:5000/student_list/2/
@app.route('/student_list/<int:student_id>/')
def article_detail(student_id):
print(student_id, type(student_id))
return '学生{}号的信息'.format(student_id)
主要有这几种类型过滤:
string
: 默认的数据类型,接收没有任何斜杠" /"的字符串
int
: 整型
float
: 浮点型
path
: 和string类型相似,但是接受斜杠,如:可以接受参数/aa/bb/cc/多条放在一起
uuid
: 只接受uuid格式的字符串字符串,
✔提示:uuid为全宇宙唯一的串
上面几种约束均为如下格式,例子中的int可以换为 string,float,path,uuid
:
@app.route('/student_list/<int:student_id>/')
def article_detail(student_id):
return '学生{}号的信息'.format(student_id)
any
: 可以指定多种路径,如下面的例子
url_path的变量名是自己定义的
@app.route('/<any(student,class):url_path>/<id>/')
def item(url_path, id):
if url_path == 'student':
return '学生{}详情'.format(id)
else:
return '班级{}详情'.format(id)
动态路由的适用场景?
如果想增加网站的曝光率,可以考虑使用动态路由,因为是把path作为参数,搜索引擎的算法会定义你为一个静态页面,不会经常改变,有利于搜索引擎的优化。但是如果是公司内部的管理系统就没有必要使用动态路由,因为内部系统对曝光率没有要求。
关键词:
- 上面我们接受参数使用的是path(路径)形式,这种传参的形式就叫动态路由传参,有利于搜索引擎的优化。
url_for()的使用
利用视图函数名字一般不会改变的特性,根据视图函数的名字去动态精准的获取url,以便于开发使用。
url_for('视图函数名字') # 输出该视图函数url
具体例子:
from flask import Flask,url_for
app = Flask(__name__)
app.config.update(DEBUG=True)
@app.route('/')
def demo1():
print(url_for("book")) # 注意这个引用的是视图函数的名字 字符串格式
print(type(url_for("book")))
return url_for("book")
@app.route('/book_list/')
def book():
return 'flask_book'
if __name__ == "__main__":
app.run()
url_for如何处理动态的视图函数
如果想获取动态路由,必须以关键字实参的形式为动态的path部分赋值,注意动态的path部分必须被赋值,
案例:
@app.route('/demo2/')
def demo2():
student_url = url_for('student', id=5, name='mark') # id 就是动态path的key 必须赋值, # name 将作为查询字符串传入
print(student_url)
return student_url
@app.route('/student/<int:id>/')
def student(id):
return 'student {}'.format(id)
控制台输出:
浏览器输出:
url_for如何为url添加查询字符串
如果想在路径后面拼出来查询字符串,以关键字实参的形式放到url_for()里面作为参数,会自动拼成路径
案例:
@app.route('/demo3/')
def demo3():
school_url = url_for('school', school_level='high', name='college')
# 具体要拼接的查询参数 以关键字实参的形式写在url_for里
print(school_url)
return school_url
@app.route('/school/')
def school():
return 'school message'
控制台输出:
浏览器输出:
自定义转化器(非重点)
# 非重点
#1 写类,继承BaseConverter
#2 注册:app.url_map.converters['regex'] = RegexConverter
# 3 使用:@app.route('/index/<regex("d+"):nid>') 正则表达式会当作第二个参数传递到类中
from flask import Flask, url_for
from werkzeug.routing import BaseConverter
app = Flask(import_name=__name__)
class RegexConverter(BaseConverter):
"""
自定义URL匹配正则表达式
"""
def __init__(self, map, regex):
super(RegexConverter, self).__init__(map)
self.regex = regex
def to_python(self, value):
"""
路由匹配时,匹配成功后传递给视图函数中参数的值
"""
print("to_python",value,type(value))
return int(value)+1
def to_url(self, value):
"""
使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
"""
val = super(RegexConverter, self).to_url(value)
return val+"222"
# 添加到flask中
app.url_map.converters['regex'] = RegexConverter
# 正则匹配处理结果,要交给to_python,to_python函数可以对匹配处理结果做处理
@app.route('/index/<regex("d+"):nid>')
def index(nid):
print("index",nid,type(nid))
print(url_for('index', nid='888'))
return 'Index'
if __name__ == '__main__':
app.run()
总结:
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,进行处理。处理以后,在拼接到路由。