Skip to content
guyskk edited this page Mar 29, 2020 · 5 revisions

Model class is a convenient way to use schema, it's inspired by data class but works differently, it's much simpler and easy to use.

Define a base model

you can provide compiler and/or make the model immutable:

from validr import T, modelclass, asdict, fields, Invalid, ModelInvalid

@modelclass # or @modelclass(compiler=compiler, immutable=False)
class Model:
    # define common fields and methods here
    # __init__, __repr__ and __eq__ will auto created if not exists

    # do something after init
    def __post_init__(self):
        pass

Define models by inheritance

class User(Model):
    id = T.int
    age = T.int.default(18)
    name = T.str

# play with typing
class User(Model):
    id: int = T.int
    age: int = T.int.default(18)
    name: str = T.str

# nested models
class Room(Model):
    teacher = T.model(User)
    students = T.list(T.model(User))

Schema slice

UserID = User['id']
assert UserID == T.int
Lite = User['id', 'name']
assert Lite == T.dict(
    id=T.int,
    name=T.str,
)

Use the model

user = User(id=1, name='test')
# convert model to dict
asdict(user)
# get fields
fields(user)  # or fields(User)
# get the schema
T(User)
# replace fields
user2 = User(user, name='replaced')

Validate

>>> user.id = 'abc'
...
validr._exception.Invalid: id: invalid int, value=abc
>>> User(id='abc')
...
validr._exception.ModelInvalid:
+------+-------------+
| Key  | Error       |
+------+-------------+
| name | required    |
| id   | invalid int |
+------+-------------+

Handle invalid

try:
    User(id='abc')
except ModelInvalid as ex:
    for error in ex.errors:
        print(error.position, error.message)
>>>
name required
id invalid int

The ModelInvalid.errors is a list of Invalid instances, see Usage-&-API#handle-exception.