JSONLINT:python的json数据验证库实例解析


Posted in Python onNovember 28, 2017

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写。

JSON 函数

使用 JSON 函数需要导入 json 库:import json。

函数 描述
json.dumps 将 Python 对象编码成 JSON 字符串
json.loads 将已编码的 JSON 字符串解码为 Python 对象

随着前后端分离和 REST APIs 的火热,开发者不断寻找着一种灵活的、优雅的方式验证 json 数据。有直接手动获取数据验证的,也有使用 json scheme 验证的。前者容易使得函数变得冗长,还可能存在不少重复的验证;后者验证又不灵活。

本文介绍的 jsonlint 启发自 python 的表单验证工具 wtforms,wtforms 通过继承 Form 类也能进行 json 数据验证,但是 wtforms 对于 json 的数组(Array)类型处理有着很诡异的行为,需要通过 a-1 、 a-2 这样来传递数组数据,常常不能有效的处理数组数据。 jsonlint 大部分代码来着 wtforms,可以视为 wtforms 的一个分支。但 jsonlint 删去了 wtforms 的表单渲染部分,更改了传入的数据格式,最重要的是使用正确的逻辑验证数组(Array)和对象(Object)类型。下面是一些例子:

基本的字符串类型json验证

对于基本的字符串类型,我们只需要创建一个 Json 的子类,填写对应的 Field 即可。使用方式和 wtforms 类型:

from jsonlint import Json
from jsonlint.fields import StringField
from jsonlint.validators import DataRequired
class MyLint(Json):
 name = StringField(validators=[DataRequired()])
mylint = MyLint({'name': 'demo'})
print mylint.validate() # True
print mylint.name.data # demo

更灵活的验证 json 数据

jsonlint 继承了 wtforms 的优点,可以进行一些更灵活的自定义json数据验证,只要将 field 类的实例名写成函数 validate_fieldname ,即可自定义验证改字段:

from jsonlint import Json
from jsonlint.fields import IntegerField
from jsonlint.validators import ValidationError
class AgeLint(Json):
 age = IntegerField()
 def validate_age(form, field):
  if field.data < 13:
   raise ValidationError("We're sorry, you must be 13 or older to register")
agelint = AgeLint({'age': 12})
print agelint.validate() # False
print agelint.age.errors # ["We're sorry, you must be 13 or older to register"]

对数组类型进行验证

jsonlint 诞生可以说主要就是为了解决如何验证数组类型的问题,在jsonlint这很容易实现:

from jsonlint import Json
from jsonlint.fields import StringField, ListField
from jsonlint.validators import DataRequired, ValidationError
class ListLint(Json):
 cars = ListField(StringField(validators=[DataRequired()]))
 def validate_cars(form, field):
  if 'BMW' in field.data:
   raise ValidationError("We're sorry, you cannot drive BMW")
listlint = ListLint({'cars': ['Benz', 'BMW', 'Audi']})
print listlint.validate() # False
print listlint.cars.errors # ["We're sorry, you cannot drive BMW"]

ListField 类作为一个 Field 容器,容纳其它类型 Field 的数组,将对应类型的数组直接传入,即可有效的验证;ListField 同样也可以进行自定义验证。

对对象类型进行验证

对象类型在一些 REST APIs 的 web 应用中也经常存在,对此 jsonlint 也作了支持。只要将 Json 子类传入 ObjectField 中即可进行验证:

from jsonlint import Json
from jsonlint.fields import ObjectField, IntegerField, BooleanField
class T(Json):
 status = BooleanField()
 code = IntegerField()
class DataLint(Json):
 data = ObjectField(T)
datalint = DataLint({'data': {'status': True, 'code': 200}})
print datalint.validate() # False
print datalint.data.code.data # 200

写在最后

jsonlint 诞生初衷就是因为本人想用类似 wtforms 的方式来验证json,这样不但有着良好的验证方式,还可以分割业务,避免接口主函数变得十分冗长。例如,可以定义类:

class RegisterLint(UserLint):
 def validata_nickname(self, field):
  ...
 def validate_account(self, field):
  ...
 def create_user(self):
  ...
user = RegisterLint()

这样既可以使用 RegisterLint 的实例 user 验证数据,同时又能直接执行 user.create_user() 进行数据库操作,将数据库逻辑更好的封装。这样可以说是在 MVC 设计模式的基础上独立出了一层。

想要尝试使用 jsonlint 可以直接使用 pip 安装:

pip install jsonlint

最后,jsonlint 开源在 Github : https://github.com/tangwz/jsonlint

jsonlint 现阶段仅由我一人维护,虽然单元测试覆盖率尽可能的全覆盖,但也不代表没有bug,希望您提出您宝贵的意见,或一起维护、迭代jsonlint:

https://github.com/tangwz/jsonlint/issues

如果使用 Flask 进行 web 开发,也可以使用封装好的结合了 Flask 和 jsonlint 的库: Flask-Lint

Python 相关文章推荐
Python中除法使用的注意事项
Aug 21 Python
Python基于Tkinter的HelloWorld入门实例
Jun 17 Python
Python编程实战之Oracle数据库操作示例
Jun 21 Python
TensorFlow实现Softmax回归模型
Mar 09 Python
python实现自动解数独小程序
Jan 21 Python
Python实现的删除重复文件或图片功能示例【去重】
Apr 23 Python
Django框架使用内置方法实现登录功能详解
Jun 12 Python
python GUI库图形界面开发之PyQt5布局控件QHBoxLayout详细使用方法与实例
Mar 06 Python
Pycharm激活码激活两种快速方式(附最新激活码和插件)
Mar 12 Python
Python多进程multiprocessing、进程池用法实例分析
Mar 24 Python
Pycharm安装python库的方法
Nov 24 Python
用python爬虫批量下载pdf的实现
Dec 01 Python
详解如何使用Python编写vim插件
Nov 28 #Python
从头学Python之编写可执行的.py文件
Nov 28 #Python
浅谈用Python实现一个大数据搜索引擎
Nov 28 #Python
Python中用psycopg2模块操作PostgreSQL方法
Nov 28 #Python
Python搜索引擎实现原理和方法
Nov 27 #Python
python输入错误密码用户锁定实现方法
Nov 27 #Python
动态规划之矩阵连乘问题Python实现方法
Nov 27 #Python
You might like
PHP文件下载类
2006/12/06 PHP
php实现的太平洋时间和北京时间互转的自定义函数分享
2014/08/19 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
laravel开发环境homestead搭建过程详解
2020/07/03 PHP
Jquery ThickBox插件使用心得(不建议使用)
2010/09/08 Javascript
基于jquery的点击链接插入链接内容的代码
2012/07/31 Javascript
js实现div的切换特效上一个下一个
2014/02/11 Javascript
jQuery实现当前页面标签高亮显示的方法
2015/03/10 Javascript
原生JS取代一些JQuery方法的简单实现
2016/09/20 Javascript
jQuery css() 方法动态修改CSS属性
2016/09/25 Javascript
微信小程序授权获取用户详细信息openid的实例详解
2017/09/20 Javascript
layui select获取自定义属性方法
2018/08/15 Javascript
Phaser.js实现简单的跑酷游戏附源码下载
2018/10/26 Javascript
JS实现数组去重,显示重复元素及个数的方法示例
2019/01/21 Javascript
Python中的作用域规则详解
2015/01/30 Python
详解Python设计模式编程中观察者模式与策略模式的运用
2016/03/02 Python
举例讲解Python编程中对线程锁的使用
2016/07/12 Python
Python中序列的修改、散列与切片详解
2017/08/27 Python
关于Python如何避免循环导入问题详解
2017/09/14 Python
Sanic框架异常处理与中间件操作实例分析
2018/07/16 Python
python 统计一个列表当中的每一个元素出现了多少次的方法
2018/11/14 Python
打包python 加icon 去掉cmd黑窗口方法
2019/06/24 Python
python 控制台单行刷新,多行刷新实例
2020/02/19 Python
css3绘制百度的小度熊
2018/10/29 HTML / CSS
css3动画事件—webkitAnimationEnd与计时器time事件
2013/01/31 HTML / CSS
澳大利亚领先的宠物用品商店:VetSupply
2017/09/08 全球购物
alice McCALL官网:澳大利亚时尚品牌
2020/11/16 全球购物
JavaScript实现页面动态验证码的实现示例
2021/03/23 Javascript
大学毕业自我鉴定范文
2014/02/03 职场文书
小学生母亲节演讲稿
2014/05/07 职场文书
学校校庆演讲稿
2014/05/22 职场文书
企业党建工作汇报材料
2014/08/19 职场文书
先进基层党组织材料
2014/12/25 职场文书
导游词之长城八达岭
2019/09/24 职场文书
Python实现的扫码工具居然这么好用!
2021/06/07 Python
HTML5 语义化标签(移动端必备)
2021/08/23 HTML / CSS