diff options
| author | Jacob Kaplan-Moss <jacob@jacobian.org> | 2008-08-31 20:10:50 +0000 |
|---|---|---|
| committer | Jacob Kaplan-Moss <jacob@jacobian.org> | 2008-08-31 20:10:50 +0000 |
| commit | 4ae746b574a84e30a8be4f207c9f386fa09c03f9 (patch) | |
| tree | 5b77386f6a88c6d4bfcea16829b418f259e66b55 /django/forms/fields.py | |
| parent | 3e71a684b35066285034f05efed5bb83dc1cf644 (diff) | |
Added a `TypedChoiceField` which acts just like `ChoiceField`, except that it
returns a value coerced by some provided function. Refs #6967.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8771 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/forms/fields.py')
| -rw-r--r-- | django/forms/fields.py | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/django/forms/fields.py b/django/forms/fields.py index b582659099..e267498808 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -23,6 +23,7 @@ try: except NameError: from sets import Set as set +import django.core.exceptions from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import smart_unicode, smart_str @@ -39,6 +40,7 @@ __all__ = ( 'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField', 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', 'SplitDateTimeField', 'IPAddressField', 'FilePathField', 'SlugField', + 'TypedChoiceField' ) # These values, if given to to_python(), will trigger the self.required check. @@ -657,6 +659,33 @@ class ChoiceField(Field): return True return False +class TypedChoiceField(ChoiceField): + def __init__(self, *args, **kwargs): + self.coerce = kwargs.pop('coerce', lambda val: val) + self.empty_value = kwargs.pop('empty_value', '') + super(TypedChoiceField, self).__init__(*args, **kwargs) + + def clean(self, value): + """ + Validate that the value is in self.choices and can be coerced to the + right type. + """ + value = super(TypedChoiceField, self).clean(value) + if value == self.empty_value or value in EMPTY_VALUES: + return self.empty_value + + # Hack alert: This field is purpose-made to use with Field.to_python as + # a coercion function so that ModelForms with choices work. However, + # Django's Field.to_python raises django.core.exceptions.ValidationError, + # which is a *different* exception than + # django.forms.utils.ValidationError. So unfortunatly we need to catch + # both. + try: + value = self.coerce(value) + except (ValueError, TypeError, django.core.exceptions.ValidationError): + raise ValidationError(self.error_messages['invalid_choice'] % {'value': value}) + return value + class MultipleChoiceField(ChoiceField): hidden_widget = MultipleHiddenInput widget = SelectMultiple |
