{ D }
V3.2.0

Usage

Field


Field can be defined with validation chain, and will be validated when value is assigned. For example:

from dictify import Field

username = Field(required=True).instance(str).match('[a-zA-Z0-9 ._-]+$')
email = Field(required=True).instance(str).match('.+@.+')

username.value = 'user'
email.value = 'user@example.com'

username.value = 0 # Invalid, value is not assigned.
email.value = 'user' # Invalid, value is not assigned.

Model


For complex or nested data structure, Feild can be defined and managed by Model which map and validate Field to python native dict instance. For example:

from dictify import Field, Model

class Contact(Model):
    type = Field(require=True).instance(str)\
        .verify(lambda value: value in ['phone', 'email', 'address'])
    note = Field().instance(str)\
        .verify(lambda value: len(value) <= 250)
    value = Field(require=True).instance(str)\
        .verify(lambda value: len(value) <= 1000)

class User(Model):
    username = Field(required=True).instance(str).match('[a-zA-Z0-9 ._-]+$')
    email = Field(required=True).instance(str).match('.+@.+')
    contacts = Field().listof(Contact)

user = User({'username': 'user', 'email': 'user@example.com'})
user['username'] = 0 # Invalid, value won't be assigned.
user['email'] = 'user' # Invalid, won't be assigned.
user['age'] = 30 # Error, undefined field.

# Strict mode

By default, Model object will be created in strict mode which won't allow value assignment on undefined field. Set strict=False at Model creation to change this behavior.

user = User({'username': 'user', 'email': 'user@example.com'}, strict=False)

# Value assignment on undefined field is allowed.
user['age'] = 30

# Native data

Model.dict() returns native data as dict and list. This could be useful to send data though network or use with pickle() when your model has Model or List in subtree.

user = User({
    'username': 'user',
    'email': 'user@example.com',
    'contacts': [Contact({type: 'phone', value: '111-800-0000'})]
})

pickle(user) # Error
pickle(user.dict()) # Ok

Partial data validation


Defined Field can be reused for partial data validation. For example, when user want to update user’s email later, User.email can be used as class attributes to validate email without create the whole User object.

email = request.args.get('email')  # pseudo code to get email sent from user.
try:
    User.email.value = email
    # To do : Update user's email to database.
except dictify.FieldError:
    # To do : Report error.

Post validation


Define post_validation() method and it will be applied everytime data is set.

class User(Model):
    username = Field(required=True).instance(str).match('[a-zA-Z0-9 ._-]+$')
    email = Field(required=True).instance(str).match('.+@.+')
    email_backup = Field(require=True).instance(str).match('.+@.+')

    def post_validation(self):
        # Email duplication check, all built-in dictionary methods can be used.
        assert self.get('email') != self.get('email_backup')