from django import newforms as forms class SeparatedValuesField(forms.Field): """ A Django newforms field which takes another newforms field during initialization and validates every item in a separated list with this field class. Please use it like this:: from django.newforms import EmailField emails = SeparatedValuesField(EmailField) You would be able to enter a string like "john@doe.com,guido@python.org" because every email address would be validated when clean() is executed. This of course also applies to any other Field class. You can define the sepator (default: ",") during initialization with the ``separator`` parameter like this:: from django.newforms import EmailField emails = SeparatedValuesField(EmailField, separator="###") If validation succeeds it returns the original data, though the already splitted value list can be accessed with the get_list() method. >>> f = SeparatedValuesField(forms.EmailField) >>> f.clean("foo@bar.com,bar@foo.com") 'foo@bar.com,bar@foo.com' >>> f.get_list() ['foo@bar.com', 'bar@foo.com'] >>> f.clean("foobar,foo@bar.com,bar@foo.com") Traceback (most recent call last): ... ValidationError: >>> u = SeparatedValuesField(forms.URLField) >>> u.clean("http://foo.bar.com,http://foobar.com") 'http://foo.bar.com,http://foobar.com' >>> u.clean("http:foo.bar.com") Traceback (most recent call last): ... ValidationError: >>> f = SeparatedValuesField(forms.EmailField, separator="###") >>> f.clean("foo@bar.com###bar@foo.com") 'foo@bar.com###bar@foo.com' >>> f.clean("foobar###foo@bar.com###bar@foo.com") Traceback (most recent call last): ... ValidationError: """ def __init__(self, base_field=None, separator=",", *args, **kwargs): super(SeparatedValuesField, self).__init__(*args, **kwargs) self.base_field = base_field self.separator = separator def clean(self, data): if not data: raise forms.ValidationError('Enter at least one value.') self.value_list = data.split(self.separator) if self.base_field is not None: base_field = self.base_field() for value in self.value_list: base_field.clean(value) return data def get_list(self): return self.value_list def _test(): import doctest doctest.testmod() if __name__ == "__main__": _test()