欢迎来到猫子酱的学习之旅
- jsonmodels.model
- 创建模型
- 用法
- 验证 validate()
- 验证器 Validators
- 自定义验证器(**)
- 默认值
- 转换为Python结构(和JSON)
- 为您的模型创建JSON模式(***) (结合Draft7Validator)
- 结构和对象中的不同名称
jsonmodels.model
创建模型
import jsonmodels # 导入
class Cat(models.Base):
name = fields.StringField(required=True)
breed = fields.StringField()
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)
car = fields.EmbeddedField(Car)
pets = fields.ListField([Cat, Dog])
用法
可以将其看作普通对象
person = Person(name='Chuck')
person.name # 'Chuck'
person.surname # None
person.populate(surname='Norris')
person.surname # 'Norris'
person.name # 'Chuck'
验证 validate()
您可以指定哪些字段是必需的,使用 .validate() 进行一个校验,校验失败会出现ValidationError。
bugs = Person(name='Bugs', surname='Bunny')
bugs.validate()
dafty = Person()
dafty.validate() # ValidationError: Field is required!
注意: 如果在初始化期间没有分配任何值,则必需字段不会引发错误,但首次尝试访问会引发错误。
dafty = Person()
dafty.name # ValidationError: Field is required!
每次分配新值时都会进行验证,因此尝试将int分配给StringField也会引发错误:(可以用作自定义校验,感觉有点类似与DRF中的序列化器了)
dafty.name = 3 # ValidationError: ('Value is wrong, expected type "basestring"', 3)
在将模型转换为JSON或JSONSchema期间,始终调用显式验证。(这句话不是很懂,好像就是一个抛出错误的方式吧)
验证器 Validators
验证器可以通过验证器关键字、作为单个验证器或验证器列表传递(因此,您不能传递扩展List的对象)。您可以尝试使用此库附带的验证器(jsonmodels.validators)。已发送的验证器会影响生成的模式 开箱即用,使用JSON模式给你的全部潜力。
自定义验证器(**)
可以与Draft7Validator结合使用。
您始终可以指定自己的验证器。自定义验证器可以是具有验证方法(优先)或函数(或可调用对象)的对象。每个验证器都必须引发异常以指示验证未通过。返回False等值不会产生任何影响。
class RangeValidator(object):
def __init__(self, min, max):
# Some logic here.
def validate(self, value):
# Some logic here.
def some_validator(value):
# Some logic here.
class Person(models.Base):
name = fields.StringField(required=True, validators=some_validator)
surname = fields.StringField(required=True)
age = fields.IntField(
Car, validators=[some_validator, RangeValidator(0, 100)])
如果您的验证器有方法modify_schema您可以使用它以任何方式影响生成的模式。给定参数是单个字段的模式。例如
class Length(object):
def validate(self, value):
# Some logic here.
def modify_schema(self, field_schema):
if self.minimum_value:
field_schema['minLength'] = self.minimum_value
if self.maximum_value:
field_schema['maxLength'] = self.maximum_value
默认值
您可以为每个字段指定默认值(此默认值将显示在生成的架构中)。目前只接受标量并为EmbeddedField的实例建模,如下例所示:
class Pet(models.Base):
kind = fields.StringField(default="Dog")
class Person(models.Base):
name = fields.StringField(default="John Doe")
age = fields.IntField(default=18)
pet = fields.EmbeddedField(Pet, default=Pet(kind="Cat"))
profession = fields.StringField(default=None)
使用此模式生成如下所示:
{
"type": "object",
"additionalProperties": false,
"properties": {
"age": {
"type": "number",
"default": 18
},
"name": {
"type": "string",
"default": "John Doe"
},
"pet": {
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"type": "string",
"default": "Dog"
}
},
"default": {
"kind": "Cat"
}
},
"profession": {
"type": "string",
"default": null
}
}
}
转换为Python结构(和JSON)
模型实例可以很容易地转换为Python结构(jsonmodels.models.PreBase.to_struct()):
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() # (...)
Python --> JSON:
import json
person_json = json.dumps(person.to_struct())
为您的模型创建JSON模式(***) (结合Draft7Validator)
JSON模式,jsonmodel,您可以只对模型进行操作。
person = Person()
schema = person.to_json_schema()
您可以通过您的API提供此模式或使用它来验证传入数据。
结构和对象中的不同名称
如果您想(或必须)在生成/使用的数据及其模式中使用不同的名称,您可以对字段使用name=参数:
class Human(models.Base):
name = fields.StringField()
surname = fields.StringField(name='second-name')
name值将在您使用对象的所有地方用作别名,并且在所有结构中都将被视为第二个名称-因此在ute表示和jsonSchema中也是如此。
>>> john = Human(name='John', surname='Doe')
>>> john.surname
'Doe'
>>> john.to_struct()
{'name': 'John', 'second-name': 'Doe'}
注意,您的模型不得具有无法通过模型解析的冲突名称。不过,您可以使用交叉引用,如下所示:
**结构名称具有优先级,因此使用上面的Foo模型,您可能会遇到错误的假设:**
class Foo(models.Base):
one = fields.IntField(name='two')
two = fields.IntField(name='one')
>>> foo = Foo(one=1, two=2)
>>> foo.one
2 # Not 1, like expected
>>> foo.two
1 # Not 2, like expected