summaryrefslogtreecommitdiff
path: root/django/forms/fields.py
diff options
context:
space:
mode:
authorJacob Kaplan-Moss <jacob@jacobian.org>2008-08-31 20:10:50 +0000
committerJacob Kaplan-Moss <jacob@jacobian.org>2008-08-31 20:10:50 +0000
commit4ae746b574a84e30a8be4f207c9f386fa09c03f9 (patch)
tree5b77386f6a88c6d4bfcea16829b418f259e66b55 /django/forms/fields.py
parent3e71a684b35066285034f05efed5bb83dc1cf644 (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.py29
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