I'm looking for something similar, and I found this: http://djangosnippets.org/snippets/497/
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: <unprintable ValidationError object> >>> 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: <unprintable ValidationError object> >>> 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: <unprintable ValidationError object> """ 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()
This is not entirely satisfactory: for example, for a list of emails, if only one message is invalid, the entire field is invalid.
You can probably rewrite the pure method so that it returns only valid "base_fields" instead of throwing a ValidationError at all.
source share