def validate(self, value): super(DecimalField, self).validate(value) if value in validators.EMPTY_VALUES: return # Check for NaN, Inf and -Inf values. We can't compare directly for NaN, # since it is never equal to itself. However, NaN is the only value that # isn't equal to itself, so we can use this to identify NaN if value != value or value == Decimal("Inf") or value == Decimal("-Inf"): raise ValidationError(self.error_messages['invalid']) sign, digittuple, exponent = value.as_tuple() decimals = abs(exponent) # digittuple doesn't include any leading zeros. digits = len(digittuple) if decimals > digits: # We have leading zeros up to or past the decimal point. Count # everything past the decimal point as a digit. We do not count # 0 before the decimal point as a digit since that would mean # we would not allow max_digits = decimal_places. digits = decimals whole_digits = digits - decimals if self.max_digits is not None and digits > self.max_digits: raise ValidationError(self.error_messages['max_digits'] % self.max_digits) if self.decimal_places is not None and decimals > self.decimal_places: raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places) if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places): raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) return value
def clean(self, value): """ Validates every value in the given list. A value is validated against the corresponding Field in self.fields. For example, if this MultiValueField was instantiated with fields=(DateField(), TimeField()), clean() would call DateField.clean(value[0]) and TimeField.clean(value[1]). """ clean_data = [] errors = ErrorList() if not value or isinstance(value, (list, tuple)): if not value or not [v for v in value if v not in validators.EMPTY_VALUES]: if self.required: raise ValidationError(self.error_messages['required']) else: return self.compress([]) else: raise ValidationError(self.error_messages['invalid']) for i, field in enumerate(self.fields): try: field_value = value[i] except IndexError: field_value = None if self.required and field_value in validators.EMPTY_VALUES: raise ValidationError(self.error_messages['required']) try: clean_data.append(field.clean(field_value)) except ValidationError, e: # Collect all validation errors in a single list, which we'll # raise at the end of clean(), rather than raising a single # exception for the first error we encounter. errors.extend(e.messages)
def validate(self, value): """ Validates that the input is a list or tuple. """ if self.required and not value: raise ValidationError(self.error_messages['required']) # Validate that each value in the value list is in self.choices. for val in value: if not self.valid_value(val): raise ValidationError(self.error_messages['invalid_choice'] % {'value': val})
def compress(self, data_list): if data_list: # Raise a validation error if time or date is empty # (possible if SplitDateTimeField has required=False). if data_list[0] in validators.EMPTY_VALUES: raise ValidationError(self.error_messages['invalid_date']) if data_list[1] in validators.EMPTY_VALUES: raise ValidationError(self.error_messages['invalid_time']) result = datetime.datetime.combine(*data_list) return from_current_timezone(result) return None
def validate(self, value): """ Validates that the input is in self.choices. """ super(ChoiceField, self).validate(value) if value and not self.valid_value(value): raise ValidationError(self.error_messages['invalid_choice'] % {'value': value})
def validate_ipv46_address(value): try: validate_ipv4_address(value) except ValidationError: try: validate_ipv6_address(value) except ValidationError: raise ValidationError(_(u'Enter a valid IPv4 or IPv6 address.'), code='invalid')
def to_python(self, value): if value in EMPTY_VALUES: return None try: key = self.to_field_name or 'pk' value = self.queryset.get(**{key: value}) except (ValueError, self.queryset.model.DoesNotExist): raise ValidationError(self.error_messages['invalid_choice']) return value
def __call__(self, value): cleaned = self.clean(value) params = {'limit_value': self.limit_value, 'show_value': cleaned} if self.compare(cleaned, self.limit_value): raise ValidationError( self.message % params, code=self.code, params=params, )
def split_url(url): """ Returns a list of url parts via ``urlparse.urlsplit`` (or raises a ``ValidationError`` exception for certain). """ try: return list(urlparse.urlsplit(url)) except ValueError: # urlparse.urlsplit can raise a ValueError with some # misformatted URLs. raise ValidationError(self.error_messages['invalid'])
def to_python(self, data): if data in validators.EMPTY_VALUES: return None # UploadedFile objects should have name and size attributes. try: file_name = data.name file_size = data.size except AttributeError: raise ValidationError(self.error_messages['invalid']) if self.max_length is not None and len(file_name) > self.max_length: error_values = {'max': self.max_length, 'length': len(file_name)} raise ValidationError(self.error_messages['max_length'] % error_values) if not file_name: raise ValidationError(self.error_messages['invalid']) if not self.allow_empty_file and not file_size: raise ValidationError(self.error_messages['empty']) return data
def to_python(self, value): """ Validates that the value is in self.choices and can be coerced to the right type. """ value = super(TypedChoiceField, self).to_python(value) super(TypedChoiceField, self).validate(value) if value == self.empty_value or value in validators.EMPTY_VALUES: return self.empty_value try: value = self.coerce(value) except (ValueError, TypeError, ValidationError): raise ValidationError(self.error_messages['invalid_choice'] % {'value': value}) return value
def to_python(self, value): """Returns a Python boolean object.""" # Explicitly check for the string 'False', which is what a hidden field # will submit for False. Also check for '0', since this is what # RadioSelect will provide. Because bool("True") == bool('1') == True, # we don't need to handle that explicitly. if isinstance(value, basestring) and value.lower() in ('false', '0'): value = False else: value = bool(value) value = super(BooleanField, self).to_python(value) if not value and self.required: raise ValidationError(self.error_messages['required']) return value
def to_python(self, data): """ Checks that the file-upload field data contains a valid image (GIF, JPG, PNG, possibly others -- whatever the Python Imaging Library supports). """ f = super(ImageField, self).to_python(data) if f is None: return None # Try to import PIL in either of the two ways it can end up installed. try: from PIL import Image except ImportError: import Image # We need to get a file object for PIL. We might have a path or we might # have to read the data into memory. if hasattr(data, 'temporary_file_path'): file = data.temporary_file_path() else: if hasattr(data, 'read'): file = StringIO(data.read()) else: file = StringIO(data['content']) try: # load() is the only method that can spot a truncated JPEG, # but it cannot be called sanely after verify() trial_image = Image.open(file) trial_image.load() # Since we're about to use the file again we have to reset the # file object if possible. if hasattr(file, 'reset'): file.reset() # verify() is the only method that can spot a corrupt PNG, # but it must be called immediately after the constructor trial_image = Image.open(file) trial_image.verify() except ImportError: # Under PyPy, it is possible to import PIL. However, the underlying # _imaging C module isn't available, so an ImportError will be # raised. Catch and re-raise. raise except Exception: # Python Imaging Library doesn't recognize it as an image raise ValidationError(self.error_messages['invalid_image']) if hasattr(f, 'seek') and callable(f.seek): f.seek(0) return f
def clean(self, value): if value in EMPTY_VALUES: if self.pk_field: return None # if there is no value act as we did before. return self.parent_instance # ensure the we compare the values as equal types. if self.to_field: orig = getattr(self.parent_instance, self.to_field) else: orig = self.parent_instance.pk if force_unicode(value) != force_unicode(orig): raise ValidationError(self.error_messages['invalid_choice']) return self.parent_instance
def to_python(self, value): """ Validates that float() can be called on the input. Returns the result of float(). Returns None for empty values. """ value = super(IntegerField, self).to_python(value) if value in validators.EMPTY_VALUES: return None if self.localize: value = formats.sanitize_separators(value) try: value = float(value) except (ValueError, TypeError): raise ValidationError(self.error_messages['invalid']) return value
def validate_unique(self, exclude=None): """ Checks unique constraints on the model and raises ``ValidationError`` if any failed. """ unique_checks, date_checks = self._get_unique_checks(exclude=exclude) errors = self._perform_unique_checks(unique_checks) date_errors = self._perform_date_checks(date_checks) for k, v in date_errors.items(): errors.setdefault(k, []).extend(v) if errors: raise ValidationError(errors)
def clean(self, value): if self.required and not value: raise ValidationError(self.error_messages['required']) elif not self.required and not value: return [] if not isinstance(value, (list, tuple)): raise ValidationError(self.error_messages['list']) key = self.to_field_name or 'pk' for pk in value: try: self.queryset.filter(**{key: pk}) except ValueError: raise ValidationError(self.error_messages['invalid_pk_value'] % pk) qs = self.queryset.filter(**{'%s__in' % key: value}) pks = set([force_unicode(getattr(o, key)) for o in qs]) for val in value: if force_unicode(val) not in pks: raise ValidationError(self.error_messages['invalid_choice'] % val) # Since this overrides the inherited ModelChoiceField.clean # we run custom validators here self.run_validators(value) return qs
def to_python(self, value): """ Validates that the values are in self.choices and can be coerced to the right type. """ value = super(TypedMultipleChoiceField, self).to_python(value) super(TypedMultipleChoiceField, self).validate(value) if value == self.empty_value or value in validators.EMPTY_VALUES: return self.empty_value new_value = [] for choice in value: try: new_value.append(self.coerce(choice)) except (ValueError, TypeError, ValidationError): raise ValidationError(self.error_messages['invalid_choice'] % {'value': choice}) return new_value
def from_current_timezone(value): """ When time zone support is enabled, convert naive datetimes entered in the current time zone to aware datetimes. """ if settings.USE_TZ and value is not None and timezone.is_naive(value): current_timezone = timezone.get_current_timezone() try: return timezone.make_aware(value, current_timezone) except Exception, e: raise ValidationError( _('%(datetime)s couldn\'t be interpreted ' 'in time zone %(current_timezone)s; it ' 'may be ambiguous or it may not exist.') % { 'datetime': value, 'current_timezone': current_timezone })
def to_python(self, value): """ Validates that the input is a decimal number. Returns a Decimal instance. Returns None for empty values. Ensures that there are no more than max_digits in the number, and no more than decimal_places digits after the decimal point. """ if value in validators.EMPTY_VALUES: return None if self.localize: value = formats.sanitize_separators(value) value = smart_str(value).strip() try: value = Decimal(value) except DecimalException: raise ValidationError(self.error_messages['invalid']) return value
def clean(self, data, initial=None): # If the widget got contradictory inputs, we raise a validation error if data is FILE_INPUT_CONTRADICTION: raise ValidationError(self.error_messages['contradiction']) # False means the field value should be cleared; further validation is # not needed. if data is False: if not self.required: return False # If the field is required, clearing is not possible (the widget # shouldn't return False data in that case anyway). False is not # in validators.EMPTY_VALUES; if a False value makes it this far # it should be validated from here on out as None (so it will be # caught by the required check). data = None if not data and initial: return initial return super(FileField, self).clean(data)
def _management_form(self): """Returns the ManagementForm instance for this FormSet.""" if self.is_bound: form = ManagementForm(self.data, auto_id=self.auto_id, prefix=self.prefix) if not form.is_valid(): raise ValidationError( 'ManagementForm data is missing or has been tampered with') else: form = ManagementForm(auto_id=self.auto_id, prefix=self.prefix, initial={ TOTAL_FORM_COUNT: self.total_form_count(), INITIAL_FORM_COUNT: self.initial_form_count(), MAX_NUM_FORM_COUNT: self.max_num }) return form
def to_python(self, value): """ Validates that the input can be converted to a datetime. Returns a Python datetime.datetime object. """ if value in validators.EMPTY_VALUES: return None if isinstance(value, datetime.datetime): return from_current_timezone(value) if isinstance(value, datetime.date): result = datetime.datetime(value.year, value.month, value.day) return from_current_timezone(result) if isinstance(value, list): # Input comes from a SplitDateTimeWidget, for example. So, it's two # components: date and time. if len(value) != 2: raise ValidationError(self.error_messages['invalid']) if value[0] in validators.EMPTY_VALUES and value[1] in validators.EMPTY_VALUES: return None value = '%s %s' % tuple(value) result = super(DateTimeField, self).to_python(value) return from_current_timezone(result)
def to_python(self, value): # Try to coerce the value to unicode. unicode_value = force_unicode(value, strings_only=True) if isinstance(unicode_value, unicode): value = unicode_value.strip() # If unicode, try to strptime against each input format. if isinstance(value, unicode): for format in self.input_formats: try: return self.strptime(value, format) except ValueError: if format.endswith('.%f'): # Compatibility with datetime in pythons < 2.6. # See: http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior if value.count('.') != format.count('.'): continue try: datetime_str, usecs_str = value.rsplit('.', 1) usecs = int(usecs_str[:6].ljust(6, '0')) dt = datetime.datetime.strptime(datetime_str, format[:-3]) return dt.replace(microsecond=usecs) except ValueError: continue raise ValidationError(self.error_messages['invalid'])
try: self.clean() except ValidationError, e: errors = e.update_error_dict(errors) # Run unique checks, but only for fields that passed validation. for name in errors.keys(): if name != NON_FIELD_ERRORS and name not in exclude: exclude.append(name) try: self.validate_unique(exclude=exclude) except ValidationError, e: errors = e.update_error_dict(errors) if errors: raise ValidationError(errors) def clean_fields(self, exclude=None): """ Cleans all fields and raises a ValidationError containing message_dict of all validation errors if any occur. """ if exclude is None: exclude = [] errors = {} for f in self._meta.fields: if f.name in exclude: continue # Skip validation for empty fields with blank=True. The developer # is responsible for making sure they have a valid value.
def __call__(self, value): """ Validates that the input matches the regular expression. """ if not self.regex.search(smart_unicode(value)): raise ValidationError(self.message, code=self.code)
def validate_ipv6_address(value): if not is_valid_ipv6_address(value): raise ValidationError(_(u'Enter a valid IPv6 address.'), code='invalid')
def validate_integer(value): try: int(value) except (ValueError, TypeError): raise ValidationError('')
"The URLField verify_exists argument has intractable security " "and performance issues. Accordingly, it has been deprecated.", DeprecationWarning ) headers = { "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", "Accept-Language": "en-us,en;q=0.5", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Connection": "close", "User-Agent": self.user_agent, } url = url.encode('utf-8') # Quote characters from the unreserved set, refs #16812 url = urllib.quote(url, "!*'();:@&=+$,/?#[]") broken_error = ValidationError( _(u'This URL appears to be a broken link.'), code='invalid_link') try: req = urllib2.Request(url, None, headers) req.get_method = lambda: 'HEAD' #Create an opener that does not support local file access opener = urllib2.OpenerDirector() #Don't follow redirects, but don't treat them as errors either error_nop = lambda *args, **kwargs: True http_error_processor = urllib2.HTTPErrorProcessor() http_error_processor.http_error_301 = error_nop http_error_processor.http_error_302 = error_nop http_error_processor.http_error_307 = error_nop handlers = [urllib2.UnknownHandler(), urllib2.HTTPHandler(),
def validate_unique(self): # Collect unique_checks and date_checks to run from all the forms. all_unique_checks = set() all_date_checks = set() for form in self.forms: if not hasattr(form, 'cleaned_data'): continue exclude = form._get_validation_exclusions() unique_checks, date_checks = form.instance._get_unique_checks( exclude=exclude) all_unique_checks = all_unique_checks.union(set(unique_checks)) all_date_checks = all_date_checks.union(set(date_checks)) errors = [] # Do each of the unique checks (unique and unique_together) for uclass, unique_check in all_unique_checks: seen_data = set() for form in self.forms: # if the form doesn't have cleaned_data then we ignore it, # it's already invalid if not hasattr(form, "cleaned_data"): continue # get data for each field of each of unique_check row_data = tuple([ form.cleaned_data[field] for field in unique_check if field in form.cleaned_data ]) if row_data and not None in row_data: # if we've aready seen it then we have a uniqueness failure if row_data in seen_data: # poke error messages into the right places and mark # the form as invalid errors.append( self.get_unique_error_message(unique_check)) form._errors[NON_FIELD_ERRORS] = self.error_class( [self.get_form_error()]) del form.cleaned_data break # mark the data as seen seen_data.add(row_data) # iterate over each of the date checks now for date_check in all_date_checks: seen_data = set() uclass, lookup, field, unique_for = date_check for form in self.forms: # if the form doesn't have cleaned_data then we ignore it, # it's already invalid if not hasattr(self, 'cleaned_data'): continue # see if we have data for both fields if (form.cleaned_data and form.cleaned_data[field] is not None and form.cleaned_data[unique_for] is not None): # if it's a date lookup we need to get the data for all the fields if lookup == 'date': date = form.cleaned_data[unique_for] date_data = (date.year, date.month, date.day) # otherwise it's just the attribute on the date/datetime # object else: date_data = (getattr(form.cleaned_data[unique_for], lookup), ) data = (form.cleaned_data[field], ) + date_data # if we've aready seen it then we have a uniqueness failure if data in seen_data: # poke error messages into the right places and mark # the form as invalid errors.append(self.get_date_error_message(date_check)) form._errors[NON_FIELD_ERRORS] = self.error_class( [self.get_form_error()]) del form.cleaned_data break seen_data.add(data) if errors: raise ValidationError(errors)