flask第十一篇——自定义url转换器

首先和大家说一下flask的组成,flask其实是werkzeug(路由和http处理)+SQLAlchemy(数据库)+Jinja2(模板)组成的,今天我们要看到的东西就是`werkzeug`里面的内容。

我们在代码里导入from werkzeug.routing import BaseConverter,然后进入BaseConverter中看一下这个方法的源码:

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

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

那么我们现在想自定义url转换器——我们希望传入的是list类型的数据,那么我们就可以参照上面代码里的形式,定义to_python和to_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]),就是说地址是在代码里传,

我们已经想好了页面的地址:

# coding: utf-8

from flask import Flask
from werkzeug.routing import BaseConverter
import flask

app = Flask(__name__)  # type: Flask
app.debug = True

# 根目录
@app.route('/')
def hello_world():

    return 'Hello World!'

class ListConverter(BaseConverter):

    def to_python(self, values):
        """
        将url中的参数转换为我们需要的数据类型
        """
        # split方法就是去掉加号并返回list类型数据
        tmp = values.split('+')
        print 'tmp: %s' % tmp
        return tmp
    
    def to_url(self, values):
        """
        将[1,2,3]转换成1+2+3
        """
        # 遍历列表values中的数据,以+连接,最后tmp1的值即1+2+3
        # BaseConverter.to_url是对url进行编码
        tmp1 = '+'.join([BaseConverter.to_url(self, value) for value in values])
        print 'tmp1:%s' % tmp1
        return tmp1


# 将写好的类注册到DEFAULT_CONVERTERS
app.url_map.converters['list'] = ListConverter

@app.route('/detail/<list:params>/')
def detail(params):
    print 'parmas:%s' % params
    return 'success for url'

with app.test_request_context():
    print 'detail函数的url是:%s' % flask.url_for('detail', params=[1, 2, 3])


if __name__ == '__main__':
    app.run()

执行代码以后刷新页面可以看到:

  • 控制台
tmp1:1+2+3
detail函数的url是:/detail/1+2+3/
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
tmp1:1+2+3
detail函数的url是:/detail/1+2+3/
 * Debugger is active!
 * Debugger PIN: 176-123-878
127.0.0.1 - - [15/Mar/2018 00:21:23] "GET /detail/1+2+3/ HTTP/1.1" 200 -
tmp: [u'1', u'2', u'3']
params:[u'1', u'2', u'3']
tmp: [u'1', u'2', u'3']
127.0.0.1 - - [15/Mar/2018 00:23:28] "GET /detail/1+2+3/ HTTP/1.1" 200 -
params:[u'1', u'2', u'3']
  • 页面 地址:http://127.0.0.1:5000/detail/1+2+3/ 页面显示:success for url

这里有点不好理解,很难理解,大家看懂更好,看不懂就知道有这么回事就好,后面还会有这里的说明的。

原文发布于微信公众号 - 自动化测试实战(gh_839e78b6ba28)

原文发表时间:2018-03-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏owent

[libiniloader] Project

Github地址: https://github.com/owt5008137/libiniloader

8410
来自专栏测试驿栈

Jmeter(三十)_TimeShift函数在JSR223中的使用

日期 - 这是日期值。用于如果要通过添加或减去特定天数,小时或分钟来创建特定日期的情况。如果参数值未通过,则使用当前日期。

39230
来自专栏佳爷的后花媛

路由&模块化设计&命名空间

ThinkPHP采用模块化的架构思想,可以支持多模块应用的创建,让应用的扩展更加方便. 先简单说下路由规则:

21530
来自专栏Python小屋

Python+pickle读写二进制文件小案例

对于二进制文件,不能使用记事本或其他文本编辑软件进行正常读写,也无法通过Python的文件对象直接读取和理解二进制文件的内容。必须正确理解二进制文件结构和序列化...

35060
来自专栏性能与架构

Zookeeper实例 - 分布式锁

需求场景 在分布式系统中,通常会有多个子系统需要操作同一资源,例如修改数据存储中的某一数据 这些子系统各自独立,操作共享资源时没有逻辑顺序,有可能会出现同时...

37650
来自专栏noteless

javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码

然后使用      65------>$ 另外一种解码方式解读,显然A就变成了$,这不就是乱码了么

20830
来自专栏用户2442861的专栏

java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?

在Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity。所有对象的非同步方法都能够在...

26910
来自专栏博客园迁移

设计模式见解

单例模式 工厂模式 map 分支扭转 接口适配 模板模式 抽象类里面具体方法封装了调用抽象方法前后的通用的逻辑 抽象方法需要子类去实现 建造者模式 使用多个简单...

6910
来自专栏电光石火

关于PHP字符编码的函数区别

在以前的学习当中,比方说有一次的写采集过程中转换字符的编码的时候老是失败,转换的结果总没有完全输出,后来经过网络查询得知是iconv有一个“-”漏洞,所以我们有...

26080
来自专栏JavaQ

Java多线程编程笔记之Condition

本篇内容基于JDK7,涉及Condition常用方法。 1.概述 Condition接口位于java.util.concurrent.locks包下,实现类有 ...

27850

扫码关注云+社区

领取腾讯云代金券