Validating and cleaning data

Processors

Before validation, any processing functions are run. These allow you do simple cleaning operations (eg calling strip on string values) before any validation rules are checked. Processors can be configured by setting processors:

class MyForm(Form):

    email = fields.Str(processors=[lambda s: s.lower().strip()])

Validators

Morf includes various common validator functions that can be configured by setting validators:

from morf import Form, fields, validators

class MyForm(Form):

    email = fields.Str(validators=[validators.is_email()])
    message = fields.Str(validators=[validators.minlen(10)])

Refer to validators for the list of built-in validation functions.

Ad-hoc validation functions

validates() lets you create ad-hoc validation functions:

from morf import Form
from morf import validates

class MyForm(Form):

    number1 = fields.Int()
    number2 = fields.Int()

    @validates(number1)
    def check_first_number_is_even(self, n1):
        if n1 % 2 != 0:
            self.fail("Even numbers only!")

    @validates(number1, number2)
    def check_second_number_is_multiple_of_first(self, n1, n2):
        if n2 % n1 != 0
            self.fail("Enter a multiple of the first number")

    @cleans(word)
    def clean_word(self, word):
        return word.lower()

cleans() works in a similar way for data cleaning functions, which are expected to return the cleaned data:

from morf import Form
from morf import cleans

class MyForm(Form):

    word = fields.Str()

    @cleans(word)
    def clean_word(self, word):
        return word.lower()

A validator or cleaner may also act on the whole form object:

@cleans
def clean_everything(self):
    self.data['word'] = self.data['word'].lower()

Validators reference

morf.validators.assert_false(predicate, message)

Raise a ValidationError if predicate is not False

morf.validators.assert_true(predicate, message)

Raise a ValidationError if predicate is not True

morf.validators.eq(expected, message=None)

Check that the value equals expected.

morf.validators.gt(n, message=None)

Check that the value is > n.

morf.validators.gte(n, message=None)

Check that the value is ≥ n.

morf.validators.is_email(message='Enter a valid email address', _match=<built-in method match of re.Pattern object>)

Check that the value is superficially like an email address, ie that it contains a local part and domain, separated with an @.

Beyond this it is difficult to verify an email address (and technically valid RFC2822 email addresses may still break your application code - the range of what counts as valid is notoriously wide). The only way to know for sure is for your application to send a confirmation email to the address.

morf.validators.is_in(allowed, message=None)

Check that the value is contained in the list allowed.

morf.validators.is_luhn_valid(message='Enter a valid card number')

Check that a credit card number passes the Lunh checksum algorithm

morf.validators.lt(n, message=None)

Check that the value is < n.

morf.validators.lte(n, message=None)

Check that the value is ≤ n.

morf.validators.matches(p, message=None)

Check that the string value matches the given regular expression p.

morf.validators.maxlen(n, message=None)

Check that len(value) n.

morf.validators.maxwords(n, message='Value is too long', _split=<built-in method finditer of re.Pattern object>)

Check that the value has no more than n words

morf.validators.minlen(n, message=None)

Check that len(value) n.

morf.validators.minwords(n, message='Value is too long', _split=<built-in method finditer of re.Pattern object>)

Check that the value has at least n words

morf.validators.notempty(message=None)

Check that the value is a non-empty string