To use JSON models in a project:
To create models you need to create class that inherits from
jsonmodels.models.Base (and NOT
to which although refers links in documentation) and have class attributes
which values inherits from
jsonmodels.fields.BaseField (so all other
fields classes from
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])
After that you can use it as normal object. You can pass kwargs in constructor
>>> person = Person(name='Chuck') >>> person.name 'Chuck' >>> person.surname None >>> person.populate(surname='Norris') >>> person.surname 'Norris' >>> person.name 'Chuck'
You can specify which fields are required, if required value is absent during
jsonmodels.error.ValidationError will be raised.
>>> bugs = Person(name='Bugs', surname='Bunny') >>> bugs.validate() >>> dafty = Person() >>> dafty.validate() *** ValidationError: Field is required!
Note that required fields are not raising error if no value was assigned during initialization, but first try of accessing will raise it.
>>> dafty = Person() >>> dafty.name *** ValidationError: Field is required!
Also validation is made every time new value is assigned, so trying assign int to StringField will also raise an error:
>>> dafty.name = 3 *** ValidationError: ('Value is wrong, expected type "basestring"', 3)
During casting model to JSON or JSONSchema explicite validation is always called.
Validators can be passed through validators keyword, as a single validator, or list of validators (so, as you may be expecting, you can’t pass object that extends List).
You can try to use validators shipped with this library. To get more details
jsonmodels.validators. Shipped validators affect generated schema
out of the box, to use full potential JSON schema gives you.
You can always specify your own validators. Custom validator can be object with validate method (which takes precedence) or function (or callable object).
Each validator must raise exception to indicate validation didn’t pass. Returning values like False won’t have any effect.
>>> 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)])
If your validator have method modify_schema you can use it to affect generated schema in any way. Given argument is schema for single field. For example:
>>> 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
Casting to Python struct (and JSON)¶
Instance of model can be easy casted to Python struct (and thanks to that,
later to JSON). See
>>> 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() # (...)
Having Python struct it is easy to cast it to JSON.
>>> import json >>> person_json = json.dumps(person.to_struct())
Creating JSON schema for your model¶
JSON schema, although it is far more friendly than XML schema still have something in common with its old friend: people don’t like to write it and (probably) they shouldn’t do it or even read it. Thanks to jsonmodels it is possible to you to operate just on models.
>>> person = Person() >>> schema = person.to_json_schema()
And thats it! You can serve then this schema through your API or use it for validation incoming data.