def validate(self, value, model_instance): """ Validates value and throws ValidationError. Subclasses should override this to provide validation logic. """ if not self.editable: # Skip validation for non-editable fields. return if self._choices and value: for option_key, option_value in self.choices: if isinstance(option_value, (list, tuple)): # This is an optgroup, so look inside the group for # options. for optgroup_key, optgroup_value in option_value: if value == optgroup_key: return elif value == option_key: return msg = self.error_messages['invalid_choice'] % value raise exceptions.ValidationError(msg) if value is None and not self.null: raise exceptions.ValidationError(self.error_messages['null']) if not self.blank and value in validators.EMPTY_VALUES: raise exceptions.ValidationError(self.error_messages['blank'])
def to_python(self, value): if value is None: return value try: return int(value) except (TypeError, ValueError): msg = self.error_messages['invalid'] % str(value) raise exceptions.ValidationError(msg)
def to_python(self, value): if value is None: return value try: return decimal.Decimal(value) except decimal.InvalidOperation: msg = self.error_messages['invalid'] % str(value) raise exceptions.ValidationError(msg)
def to_python(self, value): if value is None: return value if isinstance(value, datetime.datetime): return value.date() if isinstance(value, datetime.date): return value value = smart_str(value) try: parsed = parse_date(value) if parsed is not None: return parsed except ValueError: msg = self.error_messages['invalid_date'] % value raise exceptions.ValidationError(msg) msg = self.error_messages['invalid'] % value raise exceptions.ValidationError(msg)
def to_python(self, value): if value in (True, False): # if value is 1 or 0 than it's equal to True or False, but we want # to return a true bool for semantic reasons. return bool(value) if value in ('t', 'True', '1'): return True if value in ('f', 'False', '0'): return False msg = self.error_messages['invalid'] % str(value) raise exceptions.ValidationError(msg)
def to_python(self, value): if value is None: return value if isinstance(value, datetime.datetime): return value if isinstance(value, datetime.date): value = datetime.datetime(value.year, value.month, value.day) if settings.USE_TZ: # For backwards compatibility, interpret naive datetimes in # local time. This won't work during DST change, but we can't # do much about it, so we let the exceptions percolate up the # call stack. warnings.warn(u"DateTimeField received a naive datetime (%s)" u" while time zone support is active." % value, RuntimeWarning) default_timezone = timezone.get_default_timezone() value = timezone.make_aware(value, default_timezone) return value value = smart_str(value) try: parsed = parse_datetime(value) if parsed is not None: return parsed except ValueError: msg = self.error_messages['invalid_datetime'] % value raise exceptions.ValidationError(msg) try: parsed = parse_date(value) if parsed is not None: return datetime.datetime(parsed.year, parsed.month, parsed.day) except ValueError: msg = self.error_messages['invalid_date'] % value raise exceptions.ValidationError(msg) msg = self.error_messages['invalid'] % value raise exceptions.ValidationError(msg)
def to_python(self, value): if value is None: return None if value in (True, False): return bool(value) if value in ('None',): return None if value in ('t', 'True', '1'): return True if value in ('f', 'False', '0'): return False msg = self.error_messages['invalid'] % str(value) raise exceptions.ValidationError(msg)
def to_python(self, value): if value is None: return None if isinstance(value, datetime.time): return value if isinstance(value, datetime.datetime): # Not usually a good idea to pass in a datetime here (it loses # information), but this can be a side-effect of interacting with a # database backend (e.g. Oracle), so we'll be accommodating. return value.time() value = smart_str(value) try: parsed = parse_time(value) if parsed is not None: return parsed except ValueError: msg = self.error_messages['invalid_time'] % value raise exceptions.ValidationError(msg) msg = self.error_messages['invalid'] % value raise exceptions.ValidationError(msg)
class Field(object): """Base class for all field types""" # Designates whether empty strings fundamentally are allowed at the # database level. empty_strings_allowed = True # These track each time a Field instance is created. Used to retain order. # The auto_creation_counter is used for fields that Django implicitly # creates, creation_counter is used for all user-specified fields. creation_counter = 0 auto_creation_counter = -1 default_validators = [] # Default set of validators default_error_messages = { 'invalid_choice': _(u'Value %r is not a valid choice.'), 'null': _(u'This field cannot be null.'), 'blank': _(u'This field cannot be blank.'), 'unique': _(u'%(model_name)s with this %(field_label)s ' u'already exists.'), } # Generic field type description, usually overriden by subclasses def _description(self): return _(u'Field of type: %(field_type)s') % { 'field_type': self.__class__.__name__ } description = property(_description) def __init__(self, verbose_name=None, name=None, primary_key=False, max_length=None, unique=False, blank=False, null=False, db_index=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True, unique_for_date=None, unique_for_month=None, unique_for_year=None, choices=None, help_text='', db_column=None, db_tablespace=None, auto_created=False, validators=[], error_messages=None): self.name = name self.verbose_name = verbose_name self.primary_key = primary_key self.max_length, self._unique = max_length, unique self.blank, self.null = blank, null # Oracle treats the empty string ('') as null, so coerce the null # option whenever '' is a possible value. if (self.empty_strings_allowed and connection.features.interprets_empty_strings_as_nulls): self.null = True self.rel = rel self.default = default self.editable = editable self.serialize = serialize self.unique_for_date, self.unique_for_month = (unique_for_date, unique_for_month) self.unique_for_year = unique_for_year self._choices = choices or [] self.help_text = help_text self.db_column = db_column self.db_tablespace = db_tablespace or settings.DEFAULT_INDEX_TABLESPACE self.auto_created = auto_created # Set db_index to True if the field has a relationship and doesn't # explicitly set db_index. self.db_index = db_index # Adjust the appropriate creation counter, and save our local copy. if auto_created: self.creation_counter = Field.auto_creation_counter Field.auto_creation_counter -= 1 else: self.creation_counter = Field.creation_counter Field.creation_counter += 1 self.validators = self.default_validators + validators messages = {} for c in reversed(self.__class__.__mro__): messages.update(getattr(c, 'default_error_messages', {})) messages.update(error_messages or {}) self.error_messages = messages def __cmp__(self, other): # This is needed because bisect does not take a comparison function. return cmp(self.creation_counter, other.creation_counter) def __deepcopy__(self, memodict): # We don't have to deepcopy very much here, since most things are not # intended to be altered after initial creation. obj = copy.copy(self) if self.rel: obj.rel = copy.copy(self.rel) memodict[id(self)] = obj return obj def to_python(self, value): """ Converts the input value into the expected Python data type, raising django.core.exceptions.ValidationError if the data can't be converted. Returns the converted value. Subclasses should override this. """ return value def run_validators(self, value): if value in validators.EMPTY_VALUES: return errors = [] for v in self.validators: try: v(value) except exceptions.ValidationError, e: if hasattr(e, 'code') and e.code in self.error_messages: message = self.error_messages[e.code] if e.params: message = message % e.params errors.append(message) else: errors.extend(e.messages) if errors: raise exceptions.ValidationError(errors)