flask之路由详解

路由简介

在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,进行处理。处理以后,在拼接到路由。

猜你喜欢

转载自www.cnblogs.com/cnhyk/p/12755927.html
今日推荐