用于简化将结构转换为或从JSON读取的处理。
项目描述
jsonmodels 是一个库,使您更容易处理转换为或从JSON读取的结构。
免费软件:BSD许可
特性
完全在Python 3.8+上测试。
支持PyPy 3.9和3.10(有关更多详细信息,请参阅文档中的实现说明)。
创建类似Django的模型
from jsonmodels import models, fields, errors, validators class Cat(models.Base): name = fields.StringField(required=True) breed = fields.StringField() love_humans = fields.IntField(nullable=True) class Dog(models.Base): name = fields.StringField(required=True) age = fields.IntField() class Car(models.Base): registration_number = fields.StringField(required=True) engine_capacity = fields.FloatField() color = fields.StringField() class Person(models.Base): name = fields.StringField(required=True) surname = fields.StringField(required=True) nickname = fields.StringField(nullable=True) car = fields.EmbeddedField(Car) pets = fields.ListField([Cat, Dog], nullable=True)
通过属性访问值
>>> cat = Cat() >>> cat.populate(name='Garfield') >>> cat.name 'Garfield' >>> cat.breed = 'mongrel' >>> cat.breed 'mongrel'
验证模型
>>> person = Person(name='Chuck', surname='Norris') >>> person.validate() None >>> dog = Dog() >>> dog.validate() *** ValidationError: Field "name" is required!
将模型转换为python结构和JSON
>>> cat = Cat(name='Garfield') >>> dog = Dog(name='Dogmeat', age=9) >>> car = Car(registration_number='ASDF 777', color='red') >>> person = Person(name='Johny', surname='Bravo', pets=[cat, dog]) >>> person.car = car >>> person.to_struct() { 'car': { 'color': 'red', 'registration_number': 'ASDF 777' }, 'surname': 'Bravo', 'name': 'Johny', 'nickname': None, 'pets': [ {'name': 'Garfield'}, {'age': 9, 'name': 'Dogmeat'} ] } >>> import json >>> person_json = json.dumps(person.to_struct())
您不喜欢编写JSON Schema?让 jsonmodels 为您完成
>>> person = Person() >>> person.to_json_schema() { 'additionalProperties': False, 'required': ['surname', 'name'], 'type': 'object', 'properties': { 'car': { 'additionalProperties': False, 'required': ['registration_number'], 'type': 'object', 'properties': { 'color': {'type': 'string'}, 'engine_capacity': {'type': ''}, 'registration_number': {'type': 'string'} } }, 'surname': {'type': 'string'}, 'name': {'type': 'string'}, 'nickname': {'type': ['string', 'null']} 'pets': { 'items': { 'oneOf': [ { 'additionalProperties': False, 'required': ['name'], 'type': 'object', 'properties': { 'breed': {'type': 'string'}, 'name': {'type': 'string'} } }, { 'additionalProperties': False, 'required': ['name'], 'type': 'object', 'properties': { 'age': {'type': 'number'}, 'name': {'type': 'string'} } }, { 'type': 'null' } ] }, 'type': 'array' } } }
验证模型并使用影响生成的架构的验证器
>>> class Person(models.Base): ... ... name = fields.StringField( ... required=True, ... validators=[ ... validators.Regex('^[A-Za-z]+$'), ... validators.Length(3, 25), ... ], ... ) ... age = fields.IntField( ... nullable=True, ... validators=[ ... validators.Min(18), ... validators.Max(101), ... ] ... ) ... nickname = fields.StringField( ... required=True, ... nullable=True ... ) ... >>> person = Person() >>> person.age = 11 >>> person.validate() *** ValidationError: '11' is lower than minimum ('18'). >>> person.age = None >>> person.validate() None >>> person.age = 19 >>> person.name = 'Scott_' >>> person.validate() *** ValidationError: Value "Scott_" did not match pattern "^[A-Za-z]+$". >>> person.name = 'Scott' >>> person.validate() None >>> person.nickname = None >>> person.validate() *** ValidationError: Field is required! >>> person.to_json_schema() { "additionalProperties": false, "properties": { "age": { "maximum": 101, "minimum": 18, "type": ["number", "null"] }, "name": { "maxLength": 25, "minLength": 3, "pattern": "/^[A-Za-z]+$/", "type": "string" }, "nickname": {, "type": ["string", "null"] } }, "required": [ "nickname", "name" ], "type": "object" }
您还可以在需要时验证标量
>>> class Person(models.Base): ... ... name = fields.StringField( ... required=True, ... validators=[ ... validators.Regex('^[A-Za-z]+$'), ... validators.Length(3, 25), ... ], ... ) ... age = fields.IntField( ... nullable=True, ... validators=[ ... validators.Min(18), ... validators.Max(101), ... ] ... ) ... nickname = fields.StringField( ... required=True, ... nullable=True ... ) ... >>> def only_odd_numbers(item): ... if item % 2 != 1: ... raise validators.ValidationError("Only odd numbers are accepted") ... >>> class Person(models.Base): ... lucky_numbers = fields.ListField(int, item_validators=[only_odd_numbers]) ... item_validator_str = fields.ListField( ... str, ... item_validators=[validators.Length(10, 20), validators.Regex(r"\w+")], ... validators=[validators.Length(1, 2)], ... ) ... >>> Person.to_json_schema() { "type": "object", "additionalProperties": false, "properties": { "item_validator_str": { "type": "array", "items": { "type": "string", "minLength": 10, "maxLength": 20, "pattern": "/\\w+/" }, "minItems": 1, "maxItems": 2 }, "lucky_numbers": { "type": "array", "items": { "type": "number" } } } }
(注意,only_odd_numbers 不会修改架构,因为只有基于类的验证器才能做到这一点,尽管它在Python中仍将按预期工作。如果要在架构方面100%正确,请使用可以表示为json schema的基于类的验证器。)
懒加载,最适合循环引用
>>> class Primary(models.Base): ... ... name = fields.StringField() ... secondary = fields.EmbeddedField('Secondary') >>> class Secondary(models.Base): ... ... data = fields.IntField() ... first = fields.EmbeddedField('Primary')
您可以使用 模型,完整路径 path.to.Model 或相对导入 .Model 或 …Model。
使用定义来生成循环引用的方案
>>> class File(models.Base): ... ... name = fields.StringField() ... size = fields.FloatField() >>> class Directory(models.Base): ... ... name = fields.StringField() ... children = fields.ListField(['Directory', File]) >>> class Filesystem(models.Base): ... ... name = fields.StringField() ... children = fields.ListField([Directory, File]) >>> Filesystem.to_json_schema() { "type": "object", "properties": { "name": {"type": "string"} "children": { "items": { "oneOf": [ "#/definitions/directory", "#/definitions/file" ] }, "type": "array" } }, "additionalProperties": false, "definitions": { "directory": { "additionalProperties": false, "properties": { "children": { "items": { "oneOf": [ "#/definitions/directory", "#/definitions/file" ] }, "type": "array" }, "name": {"type": "string"} }, "type": "object" }, "file": { "additionalProperties": false, "properties": { "name": {"type": "string"}, "size": {"type": "number"} }, "type": "object" } } }
处理无模式数据
(请注意,使用无模式字段可能导致您的模型失去控制 - 尤其如果您是数据模式的责任人。另一方面,通常情况下,传入的数据没有定义模式,无模式字段是最佳选择。)
>>> class Event(models.Base): ... ... name = fields.StringField() ... size = fields.FloatField() ... extra = fields.DictField() >>> Event.to_json_schema() { "type": "object", "additionalProperties": false, "properties": { "extra": { "type": "object" }, "name": { "type": "string" }, "size": { "type": "float" } } }
DictField 允许传递任何值的字典(“type”: “object”),但请注意,它不会对值进行任何验证,除了字典类型。
比较 JSON 方案
>>> from jsonmodels.utils import compare_schemas >>> schema1 = {'type': 'object'} >>> schema2 = {'type': 'array'} >>> compare_schemas(schema1, schema1) True >>> compare_schemas(schema1, schema2) False
更多
有关更多示例和更详细的描述,请参阅完整文档:http://jsonmodels.rtfd.org。
历史
2.7.0 (2023-12-17)
添加了 Python 3.12,PyPy 3.9 和 3.10 支持。
移除了 Python 3.7 和 PyPy 3.8 支持。
2.6.0 (2022-10-14)
移除了 Python 3.6 支持。
添加了对 Python 3.11 的支持。
2.5.1 (2022-06-16)
指定 PyPy 版本为 PyPy 3.8。
添加了对 Python 3.10 的支持。
2.5.0 (2021-07-26)
改进了字段验证错误的错误信息。
允许验证非模型列表项。
添加了 DictField。
2.4.1 (2021-02-19)
添加了 Python 3.8 和 3.9 支持。
移除了 Python 2.7、3.3 和 3.5 支持。
2.4 (2018-12-01)
修复了长度验证器。
添加了对 Python 3.7 的支持。
2.3 (2018-02-04)
为字段添加了名称映射。
为 IntField 添加了值解析。
修复了 ECMA 正则表达式标志识别的漏洞。
2.2 (2017-08-21)
修复了时间字段,当值不是必需时。
放弃了 Python 2.6 支持。
添加了对 Python 3.6 的支持。
为字段添加了可为空的参数。
改进了模型表示。
2.1.5 (2017-02-01)
修复了 DateTimefield 在值为 None 时的错误。
修复了没有必需值的模型比较。
2.1.4 (2017-01-24)
允许根据类型和字段(而不是它们的引用)比较模型。
2.1.3 (2017-01-16)
修复了生成的方案。
改进了 JSON 序列化。
2.1.2 (2016-01-06)
修复了内存泄漏。
2.1.1 (2015-11-15)
添加了对 Python 2.6、3.2 和 3.5 的支持。
2.1 (2015-11-02)
添加了类型的懒加载。
添加了循环模型的方案生成。
改进了验证错误的可读性。
修复了列表字段的生成结构。
2.0.1 (2014-11-15)
修复了原始类型的方案生成。
2.0 (2014-11-14)
字段现在是描述符。
空的需求字段仅在显式验证期间进行验证。
向后兼容性中断
字段中的 _types 重命名为 types。
ListField 中的 _items_types 重命名为 items_types。
移除了数据转换器。
将模块 error 重命名为 errors。
移除了显式验证 - 验证发生在分配时间。
将 get_value_replacement 重命名为 get_default_value。
将模块 utils 重命名为 utilities。
1.4 (2014-07-22)
允许验证器修改生成的方案。
添加了最大值验证器。
添加了在 Python 和 ECMA 格式之间转换正则表达式的实用工具。
添加了正则表达式验证器。
添加了最小值验证器。
默认情况下,字段“validators”属性是一个空列表。
1.3.1 (2014-07-13)
修复了 BoolField 的方案生成。
1.3 (2014-07-13)
添加了新的字段(BoolField、TimeField、DateField 和 DateTimeField)。
ListField 总是不必需的。
现在可以从类本身(而不是实例)生成方案。
1.2 (2014-06-18)
修复了当值不是字典时的值填充。
添加了自定义验证器。
添加了方案比较工具。
1.1.1 (2014-06-07)
添加了将已初始化的数据填充到嵌入式字段的可能。
添加了 compare_schemas 实用工具。
1.1 (2014-05-19)
添加了文档。
添加了 JSON 方案生成。
添加了用于 PEP8 和复杂性的测试。
迁移到 Python 3.4。
添加了 PEP257 兼容性。
为字段添加了帮助文本。
1.0.5 (2014-04-14)
添加了数据转换器。
1.0.4 (2014-04-13)
列表字段现在支持简单类型。
1.0.3 (2014-04-10)
修复了与Python 3的兼容性。
修复了str和repr方法。
1.0.2 (2014-04-03)
添加了深度数据初始化。
1.0.1 (2014-04-03)
添加了populate方法。
1.0 (2014-04-02)
PyPI上的第一个稳定版本。
0.1.0 (2014-03-17)
PyPI上的第一个版本。
项目详情
下载文件
下载适用于您的平台的文件。如果您不确定选择哪一个,请了解有关安装包的更多信息。
源代码分发
构建分发
jsonmodels-2.7.0.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 8c019bf1bd252ac3e401127507d735ea0fd6ce30921802b5fc5c761cd41a18bb |
|
MD5 | 6c48bf0736333cff9eb61095ecc9dc2e |
|
BLAKE2b-256 | fef777d39f85afc8928e66737ad2ca754a2539a8202abafb5079fc36e1875bc4 |
jsonmodels-2.7.0-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 6799639f40978d27f93ba4d1a5c9a5cb54a9c63937de4e81cd0d741e32bcec9f |
|
MD5 | 41d3b650d4fd223880ea3fac2ac33c1a |
|
BLAKE2b-256 | d3198d1496e5ca6d41d02dd16d6024c3cc38a6bc9343217f41ec4f261fd904fd |