diff options
| author | Robin Munn <robin.munn@gmail.com> | 2006-12-08 15:10:09 +0000 |
|---|---|---|
| committer | Robin Munn <robin.munn@gmail.com> | 2006-12-08 15:10:09 +0000 |
| commit | 122426e7453ed638a0c5be7e8b925adcddea3889 (patch) | |
| tree | a095a661aca53e0ceee021d93a2a503783b71c14 /django/newforms/fields.py | |
| parent | dadfca08c0db567ce33284aaa8eb388cf667a836 (diff) | |
sqlalchemy: Merged revisions 4054 to 4185 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/sqlalchemy@4186 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/newforms/fields.py')
| -rw-r--r-- | django/newforms/fields.py | 81 |
1 files changed, 45 insertions, 36 deletions
diff --git a/django/newforms/fields.py b/django/newforms/fields.py index 54089cb3c3..fada75fe5d 100644 --- a/django/newforms/fields.py +++ b/django/newforms/fields.py @@ -2,7 +2,8 @@ Field classes """ -from util import ValidationError, DEFAULT_ENCODING +from django.utils.translation import gettext +from util import ValidationError, smart_unicode from widgets import TextInput, CheckboxInput, Select, SelectMultiple import datetime import re @@ -28,6 +29,9 @@ except NameError: class Field(object): widget = TextInput # Default widget to use when rendering this type of Field. + # Tracks each time a Field instance is created. Used to retain order. + creation_counter = 0 + def __init__(self, required=True, widget=None): self.required = required widget = widget or self.widget @@ -35,6 +39,10 @@ class Field(object): widget = widget() self.widget = widget + # Increase the creation counter, and save our local copy. + self.creation_counter = Field.creation_counter + Field.creation_counter += 1 + def clean(self, value): """ Validates the given value and returns its "cleaned" value as an @@ -43,7 +51,7 @@ class Field(object): Raises ValidationError for any errors. """ if self.required and value in EMPTY_VALUES: - raise ValidationError(u'This field is required.') + raise ValidationError(gettext(u'This field is required.')) return value class CharField(Field): @@ -55,14 +63,11 @@ class CharField(Field): "Validates max_length and min_length. Returns a Unicode object." Field.clean(self, value) if value in EMPTY_VALUES: value = u'' - if not isinstance(value, basestring): - value = unicode(str(value), DEFAULT_ENCODING) - elif not isinstance(value, unicode): - value = unicode(value, DEFAULT_ENCODING) + value = smart_unicode(value) if self.max_length is not None and len(value) > self.max_length: - raise ValidationError(u'Ensure this value has at most %d characters.' % self.max_length) + raise ValidationError(gettext(u'Ensure this value has at most %d characters.') % self.max_length) if self.min_length is not None and len(value) < self.min_length: - raise ValidationError(u'Ensure this value has at least %d characters.' % self.min_length) + raise ValidationError(gettext(u'Ensure this value has at least %d characters.') % self.min_length) return value class IntegerField(Field): @@ -72,10 +77,12 @@ class IntegerField(Field): of int(). """ super(IntegerField, self).clean(value) + if not self.required and value in EMPTY_VALUES: + return u'' try: return int(value) except (ValueError, TypeError): - raise ValidationError(u'Enter a whole number.') + raise ValidationError(gettext(u'Enter a whole number.')) DEFAULT_DATE_INPUT_FORMATS = ( '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06' @@ -107,7 +114,7 @@ class DateField(Field): return datetime.date(*time.strptime(value, format)[:3]) except ValueError: continue - raise ValidationError(u'Enter a valid date.') + raise ValidationError(gettext(u'Enter a valid date.')) DEFAULT_DATETIME_INPUT_FORMATS = ( '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' @@ -143,7 +150,7 @@ class DateTimeField(Field): return datetime.datetime(*time.strptime(value, format)[:6]) except ValueError: continue - raise ValidationError(u'Enter a valid date/time.') + raise ValidationError(gettext(u'Enter a valid date/time.')) class RegexField(Field): def __init__(self, regex, error_message=None, required=True, widget=None): @@ -156,7 +163,7 @@ class RegexField(Field): if isinstance(regex, basestring): regex = re.compile(regex) self.regex = regex - self.error_message = error_message or u'Enter a valid value.' + self.error_message = error_message or gettext(u'Enter a valid value.') def clean(self, value): """ @@ -165,10 +172,9 @@ class RegexField(Field): """ Field.clean(self, value) if value in EMPTY_VALUES: value = u'' - if not isinstance(value, basestring): - value = unicode(str(value), DEFAULT_ENCODING) - elif not isinstance(value, unicode): - value = unicode(value, DEFAULT_ENCODING) + value = smart_unicode(value) + if not self.required and value == u'': + return value if not self.regex.search(value): raise ValidationError(self.error_message) return value @@ -180,7 +186,7 @@ email_re = re.compile( class EmailField(RegexField): def __init__(self, required=True, widget=None): - RegexField.__init__(self, email_re, u'Enter a valid e-mail address.', required, widget) + RegexField.__init__(self, email_re, gettext(u'Enter a valid e-mail address.'), required, widget) url_re = re.compile( r'^https?://' # http:// or https:// @@ -198,7 +204,7 @@ except ImportError: class URLField(RegexField): def __init__(self, required=True, verify_exists=False, widget=None, validator_user_agent=URL_VALIDATOR_USER_AGENT): - RegexField.__init__(self, url_re, u'Enter a valid URL.', required, widget) + RegexField.__init__(self, url_re, gettext(u'Enter a valid URL.'), required, widget) self.verify_exists = verify_exists self.user_agent = validator_user_agent @@ -215,12 +221,12 @@ class URLField(RegexField): "User-Agent": self.user_agent, } try: - req = urllib2.Request(field_data, None, headers) + req = urllib2.Request(value, None, headers) u = urllib2.urlopen(req) except ValueError: - raise ValidationError(u'Enter a valid URL.') + raise ValidationError(gettext(u'Enter a valid URL.')) except: # urllib2.URLError, httplib.InvalidURL, etc. - raise ValidationError(u'This URL appears to be a broken link.') + raise ValidationError(gettext(u'This URL appears to be a broken link.')) return value class BooleanField(Field): @@ -244,13 +250,12 @@ class ChoiceField(Field): """ value = Field.clean(self, value) if value in EMPTY_VALUES: value = u'' - if not isinstance(value, basestring): - value = unicode(str(value), DEFAULT_ENCODING) - elif not isinstance(value, unicode): - value = unicode(value, DEFAULT_ENCODING) + value = smart_unicode(value) + if not self.required and value == u'': + return value valid_values = set([str(k) for k, v in self.choices]) if value not in valid_values: - raise ValidationError(u'Select a valid choice. %s is not one of the available choices.' % value) + raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % value) return value class MultipleChoiceField(ChoiceField): @@ -261,27 +266,31 @@ class MultipleChoiceField(ChoiceField): """ Validates that the input is a list or tuple. """ - if not isinstance(value, (list, tuple)): - raise ValidationError(u'Enter a list of values.') if self.required and not value: - raise ValidationError(u'This field is required.') + raise ValidationError(gettext(u'This field is required.')) + elif not self.required and not value: + return [] + if not isinstance(value, (list, tuple)): + raise ValidationError(gettext(u'Enter a list of values.')) new_value = [] for val in value: - if not isinstance(val, basestring): - value = unicode(str(val), DEFAULT_ENCODING) - elif not isinstance(val, unicode): - value = unicode(val, DEFAULT_ENCODING) - new_value.append(value) + val = smart_unicode(val) + new_value.append(val) # Validate that each value in the value list is in self.choices. - valid_values = set([k for k, v in self.choices]) + valid_values = set([smart_unicode(k) for k, v in self.choices]) for val in new_value: if val not in valid_values: - raise ValidationError(u'Select a valid choice. %s is not one of the available choices.' % val) + raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % val) return new_value class ComboField(Field): def __init__(self, fields=(), required=True, widget=None): Field.__init__(self, required, widget) + # Set 'required' to False on the individual fields, because the + # required validation will be handled by ComboField, not by those + # individual fields. + for f in fields: + f.required = False self.fields = fields def clean(self, value): |
