diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 348ee977..4181bcd5 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -1080,5 +1080,11 @@ class BaseDocument(object): """Return the display value for a choice field""" value = getattr(self, field.name) if field.choices and isinstance(field.choices[0], (list, tuple)): - return dict(field.choices).get(value, value) + if value is None: + return None + sep = getattr(field, 'display_sep', ' ') + values = value if field.__class__.__name__ in ('ListField', 'SortedListField') else [value] + return sep.join([ + dict(field.choices).get(val, val) + for val in values or []]) return value diff --git a/mongoengine/base/fields.py b/mongoengine/base/fields.py index e2b5d321..69034d5d 100644 --- a/mongoengine/base/fields.py +++ b/mongoengine/base/fields.py @@ -213,8 +213,10 @@ class BaseField(object): ) ) # Choices which are types other than Documents - elif value not in choice_list: - self.error('Value must be one of %s' % six.text_type(choice_list)) + else: + values = value if isinstance(value, (list, tuple)) else [value] + if len(set(values) - set(choice_list)): + self.error('Value must be one of %s' % six.text_type(choice_list)) def _validate(self, value, **kwargs): # Check the Choices Constraint diff --git a/tests/fields/fields.py b/tests/fields/fields.py index f86ffdb4..0b9710c3 100644 --- a/tests/fields/fields.py +++ b/tests/fields/fields.py @@ -920,6 +920,12 @@ class FieldTest(MongoDBTestCase): def test_list_validation(self): """Ensure that a list field only accepts lists with valid elements.""" + AccessLevelChoices = ( + ('a', u'Administration'), + ('b', u'Manager'), + ('c', u'Staff'), + ) + class User(Document): pass @@ -934,6 +940,7 @@ class FieldTest(MongoDBTestCase): authors_as_lazy = ListField(LazyReferenceField(User)) generic = ListField(GenericReferenceField()) generic_as_lazy = ListField(GenericLazyReferenceField()) + access_list = ListField(choices=AccessLevelChoices, display_sep=', ') User.drop_collection() BlogPost.drop_collection() @@ -951,6 +958,17 @@ class FieldTest(MongoDBTestCase): post.tags = ('fun', 'leisure') post.validate() + post.access_list = 'a,b' + self.assertRaises(ValidationError, post.validate) + + post.access_list = ['c', 'd'] + self.assertRaises(ValidationError, post.validate) + + post.access_list = ['a', 'b'] + post.validate() + + self.assertEqual(post.get_access_list_display(), u'Administration, Manager') + post.comments = ['a'] self.assertRaises(ValidationError, post.validate) post.comments = 'yay'