Flask路由

时间:2024-01-26 14:18:41

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