@@ 0,0 1,101 @@
+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 :attr:`~morf.fields.Field.processors`:
+
+.. code:: python
+
+ 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 :attr:`~morf.fields.Field.validators`:
+
+.. code:: python
+
+ 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 :mod:`~morf.validators` for the list of built-in validation functions.
+
+
+Ad-hoc validation functions
+---------------------------
+
+:meth:`~morf.form.validates` lets you create ad-hoc validation functions:
+
+
+.. code:: python
+
+ 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()
+
+
+:meth:`~morf.form.cleans` works in a similar way for data cleaning functions,
+which are expected to return the cleaned data:
+
+.. code:: python
+
+ 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:
+
+.. code:: python
+
+
+ @cleans
+ def clean_everything(self):
+ self.data['word'] = self.data['word'].lower()
+
+
+
+Validators reference
+---------------------
+
+
+.. automodule:: morf.validators
+ :members:
+
@@ 66,45 66,75 @@ def assert_false(predicate, message):
return True
-def minlen(l, message=None):
- return lambda v: assert_true(len(v) >= l, message)
+def minlen(n, message=None):
+ """
+ Check that ``len(value) ≥ n``.
+ """
+ return lambda v: assert_true(len(v) >= n, message)
-def maxlen(l, message=None):
- return lambda v: assert_true(len(v) <= l, message)
+def maxlen(n, message=None):
+ """
+ Check that ``len(value) ≤ n``.
+ """
+ return lambda v: assert_true(len(v) <= n, message)
-def gt(l, message=None):
- return lambda v: assert_true(v > l, message)
+def gt(n, message=None):
+ """
+ Check that the value is > ``n``.
+ """
+ return lambda v: assert_true(v > n, message)
-def gte(l, message=None):
- return lambda v: assert_true(v >= l, message)
+def gte(n, message=None):
+ """
+ Check that the value is ≥ ``n``.
+ """
+ return lambda v: assert_true(v >= n, message)
-def lt(l, message=None):
- return lambda v: assert_true(v < l, message)
+def lt(n, message=None):
+ """
+ Check that the value is < ``n``.
+ """
+ return lambda v: assert_true(v < n, message)
-def lte(l, message=None):
- return lambda v: assert_true(v <= l, message)
+def lte(n, message=None):
+ """
+ Check that the value is ≤ ``n``.
+ """
+ return lambda v: assert_true(v <= n, message)
def matches(p, message=None):
+ """
+ Check that the string value matches the given regular expression ``p``.
+ """
if isinstance(p, _strtypes):
p = re.compile(p)
return lambda v: assert_true(p.search(v) is not None, message)
def notempty(message=None):
+ """
+ Check that the value is a non-empty string
+ """
return matches(re.compile(r"\S"), message)
def eq(expected, message=None):
+ """
+ Check that the value equals ``expected``.
+ """
return lambda v: assert_true(v == expected, message)
def is_in(allowed, message=None):
+ """
+ Check that the value is contained in the list ``allowed``.
+ """
return lambda v: assert_true(v in allowed, message)
@@ 161,9 191,7 @@ def is_luhn_valid(message="Enter a valid
digits = [int(x) for x in cc if x in string.digits]
result = (
- sum(
- digits[::-2] + [sum(divmod(d * 2, 10)) for d in digits[-2::-2]]
- )
+ sum(digits[::-2] + [sum(divmod(d * 2, 10)) for d in digits[-2::-2]])
% 10
)
return assert_true(result == 0, message)