美文网首页
flask笔记(八):动态路由设置

flask笔记(八):动态路由设置

作者: warmsirius | 来源:发表于2019-08-28 07:50 被阅读0次

一、flask转换器

前面文章中所遇到的都是简单路由,而且是固定的路由,本篇文章来讲解一下动态路由,还有正则路由,以及如何自定义路由转换器。

二、动态路由

动态路由主要指需要传入参数的路由。

在flask中,参数默认是string,但是也可以指定其他类型,比如数字int等。

变量名需要传入装饰的视图函数中,格式为:

@app.route('xxx/< converter:variable_name>')
def yyy(variable_name):
    pass

其中convert是转换器,flask中主要有以下4种基本类型转换器

类型 说明
string 默认,可以不用写
int 接受整数
float 同int,但是接受浮点数
path 和默认的string相似,但接受斜线
@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return 'User %s' % username

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id

二、基础转换器:BaseConverter

现在有个需求,如果需要传入的URL参数是一个正则式的匹配结果。

那么怎么办呢?基于上面的思路,我们发现如果传入的参数的格式是依赖于转换器的:

  • 如果是整数形式,有int转换器,
  • 如果是字符串,则默认string转换器,

这么看来,那么有没有一个方法能实现某个正则转换器呢?

当然有啦,下面来一起看看。

1.BaseConverter

Flask中所有的转换器,包括之前的int、float、path等都会继承一个BaseConverter的类;而且BaseConverter类是隐形支持正则。

BaseConverter在 flask 中的 werkzeugrouting包里。

现在我们进入源码去看看BaseConvert类:

class BaseConverter(object):
    """Base class for all converters."""

    regex = "[^/]+"
    weight = 100

    def __init__(self, map):
        self.map = map

    def to_python(self, value):
        return value

    def to_url(self, value):
        if isinstance(value, (bytes, bytearray)):
            return _fast_url_quote(value)
        return _fast_url_quote(text_type(value).encode(self.map.charset))

源码分析:

个人见解,未必正确,如有错误,还麻烦贵人能私信我,让我也改正错误,谢谢!

    1. BaseConvert类中其实定义了2个类属性,
    • regex:默认regex="[^/]+,定义了一个map是指当前映射。
    • weight:值为100
    1. 初始化函数,给每个实例使用初始化传入参数map
  • 4.实例方法:to_python

to_python 方法是将函数解析过程交给类a+b -> [a,b],使用场景没使用url_for

to_python方法的作用: 将你传过去的参数转换成对应类型的数据,比如你设置传参是uuid类型数据,那么当你传参以后,就会调用to_python方法,将参数转换为对应的uuid类型。

调用to_python时: 函数执行的是首先装饰器正则匹配提取出id ,然后id当成value传给to_python ,经to_python处理交给视图函数,相当于如果可以某个url的参数进行一些其他操作,然后传递给视图函数。

    1. 实例方法:to_url

to_url 方法to_python方法,实现了url中的参数的分割或者一些操作,url_for则是将分割和操作后的参数继续拼接成原来的URL.
也就是说,to_url方法定义了如何给url反向解析的时候显示你传入的参数.

2. 反向解析路径

学习反向解析路径,可以帮助我们更加理解BaseConverter中的to_urlto_python方法。

  • flask中使用url_for来反向解析
from flask import url_for
 # url_for根据别名来反向解析获取路由
url = url_for(endpoint指定的别名(视图函数的名字))
  • 举个例子
@app.route("/hello")
def hello():
    """欢迎页"""
    return "hello flask"

@app.route("/index", methods=['GET', 'POST'])
def index():
    """首页"""
    url = url_for("hello")
    print(url)
    return "这是首页"

输出如下:

/hello

关于带转换器的URL的反向解析

当通过反向解析传递函数时:

  • a. 首先url_for 传递给函数to_url
  • b. to_url函数对传入value值进行处理交给装饰器
  • c. 调用to_python方法,按照规则提取参数
  • d. 传入到视图函数中,执行并返回响应

三、自定义正则转换器

1、编写自定义转换器方法:

    1. 自定义类,继承BaseConverter
    1. 编写初始化方法, init方法, 接收两个参数, url_map, regex, 并初始化父类空间和子类空间
    1. 将自定义转换器类,添加到默认的转换列表中
class MyRegexConverter(BaseConverter):
    # 2.编写初始化方法, init方法, 接收两个参数, url_map, regex, 
    def __init__(self,url_map,regex):
        super(MyRegexConverter, self).__init__(url_map)  # 初始化父类空间和子类空间
        self.regex = regex  # 定义正则表达式字段

2、使用自定义转换器

  • 1、使用app.url_map.converters字典,给这个字典添加某个key,然值为你定义的转换器类名
  • 2、<key(参数):variable_name>
# 3.将自定义转换器类,添加到默认的转换列表中
app.url_map.converters['re'] = MyRegexConverter
 
#使用自定义转换器
#接收3位整数
@app.route('/<re("\d{3}"):num>')
def hello_world(num):
 
    print("num = %s"%num)
 
    return "the num is %s"%num

四、拓展

此外,下面还有 PathConverterUUIDConverter等,再往下,我们会看到,原来这里写好了一个映射,每当我们在url中传入指定类型的参数时,系统会自动的来寻找这里的映射:

#: the default converter mapping for the map.
DEFAULT_CONVERTERS = {
    "default": UnicodeConverter,
    "string": UnicodeConverter,
    "any": AnyConverter,
    "path": PathConverter,
    "int": IntegerConverter,
    "float": FloatConverter,
    "uuid": UUIDConverter,
}
  • 那么我们现在想自定义url转换器——我们希望传入的是list类型的数据,那么我们就可以参照上面代码里的形式,定义 to_pythonto_url方法,并添加到DEFAULT_CONVERTERS映射中去。

  • 现在我们假定获取到的参数是[1, 2, 3],我们要把它以1+2+3的形式在url中,那么我们to_python方法的任务就是将url中的1+2+3中的 +去掉;我们知道python的split方法可以去掉 +,但是它返回的是一个list列表,而url中地址不可能出现列表,即你不可能看到过地址是127.0.0.1:500/[1,2,3]/这种形式,所以我们另一个任务就是将数组转换成我们需要的1+2+3这种形式。

注意: 我们的url地址参数是在代码里传的就是flask.url_for('detail', params=[1, 2, 3]),就是说通过url_for传递参数函数。

相关文章

  • flask笔记(八):动态路由设置

    一、flask转换器 前面文章中所遇到的都是简单路由,而且是固定的路由,本篇文章来讲解一下动态路由,还有正则路由,...

  • 关于flask路由的思考

    flask路由 在使用flask时,我们设置路由的方式通常为: 问题来了, 我们并没有执行定义的函数,那么app....

  • angular6.x--路由

    >创建路由 >动态路由 >默认跳转路由 **>routerLinkActive设置routerLink默认选中路由...

  • flask笔记(七):简单路由设置

    一、视图支持的请求方法 flask默认的视图支持的请求方法只包括三种: GET HEAD OPTIONS 其中HE...

  • Python Web框架--框架Flask--路由(二)

    一、路由 路由通过使用Flask的app.route装饰器来设置,这类似Java的Spring Web MVC。 ...

  • Zuul第二章 Cookie和动态路由

    一、cookie的开放 二、设置动态路由

  • Service Mesh - Istio流量控制篇(上)

    动态路由:用Virtual Service和Destination Rule设置路由规则 路由这个功能是流量控制里...

  • Python学习

    python-flask框架学习(二) 1、回顾Flask 2、Flask route路由 2.1、静态路由 ap...

  • Vue实战第二天

    路由组件传参 动态路由传参 静态路由传参 函数传参htm5 history 模式 设置通用路由,找不到页面跳转自定...

  • 动态路由理解

    一、通过配置动态路由进行页面跳转同时进行参数传递 1、配置路由 2、跳转设置 ----------》注意这种方式...

网友评论

      本文标题:flask笔记(八):动态路由设置

      本文链接:https://www.haomeiwen.com/subject/wqksectx.html