diff --git a/cleancat/base.py b/cleancat/base.py index 6cd7ab0..c85bf2b 100644 --- a/cleancat/base.py +++ b/cleancat/base.py @@ -231,7 +231,8 @@ class List(Field): base_type = list blank_value = [] - def __init__(self, field_instance, **kwargs): + def __init__(self, field_instance, max_length=None, **kwargs): + self.max_length = max_length super(List, self).__init__(**kwargs) self.field_instance = field_instance @@ -240,9 +241,14 @@ def has_value(self, value): def clean(self, value): value = super(List, self).clean(value) - if self.required and not len(value): + + item_cnt = len(value) + if self.required and not item_cnt: raise ValidationError('List must not be empty.') + if self.max_length and item_cnt > self.max_length: + raise ValidationError('List is too long.') + errors = {} data = [] for n, item in enumerate(value): diff --git a/tests/__init__.py b/tests/__init__.py index e6a60de..0ea202a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -223,6 +223,9 @@ class TagsSchema(Schema): class OptionalTagsSchema(Schema): tags = List(String(), required=False) + class SmallTagsSchema(Schema): + tags = List(String(), max_length=2) + self.assertValid(TagsSchema({'tags': ['python', 'ruby']}), {'tags': ['python', 'ruby']}) self.assertInvalid(TagsSchema({'tags': []}), {'field-errors': ['tags']}) self.assertInvalid(TagsSchema({'tags': None}), {'field-errors': ['tags']}) @@ -233,6 +236,10 @@ class OptionalTagsSchema(Schema): self.assertValid(OptionalTagsSchema({'tags': None}), {'tags': []}) self.assertValid(OptionalTagsSchema({}), {'tags': []}) + self.assertValid(SmallTagsSchema({'tags': ['python', 'ruby']}), {'tags': ['python', 'ruby']}) + self.assertInvalid(SmallTagsSchema({'tags': []}), {'field-errors': ['tags']}) + self.assertInvalid(SmallTagsSchema({'tags': ['python', 'ruby', 'go']}), {'field-errors': ['tags']}) + def test_choice(self): class ChoiceSchema(Schema): choice = Choices(choices=['Hello', 'world'])