def to_internal_value(self, data): if not data or not data.startswith("data:"): raise serializers.SkipField() mime_type, file_data = parse_base64_data_uri(data) file_format = mime_type.split("/")[1] filename = f"{self.field_name}-avatar.{file_format}" return ContentFile(file_data, name=filename)
def validate_empty_values(self, column): """ Validate empty values, and either: * Raise `ValidationError`, indicating invalid data. * Raise `SkipField`, indicating that the field should be ignored. * Return (True, data), indicating an empty value that should be returned without any further validation being applied. * Return (False, data), indicating a non-empty value, that should have validation applied as normal. """ if self.read_only: return True, self.get_default() if column is serializers.empty: if getattr(self.root, 'partial', False): raise serializers.SkipField() if self.required: self.fail('required') return True, self.get_default() if column.isnull().any(): if not self.allow_null: self.fail('null') # Nullable `source='*'` fields should not be skipped when its named # field is given a null value. This is because `source='*'` means # the field is passed the entire object, which is not null. elif self.source == '*': return False, column return False, column return False, column
def validate_group(self, group: Group): # Make sure the group doesn't change if self.instance: if group and self.instance.group_id != group.group_id: raise serializers.ValidationError("Group may not be changed") # just skip this field, no need to change it raise serializers.SkipField() return group
def __call__(self, serializer_field): is_many = getattr(serializer_field.root, 'many', False) if is_many: raise serializers.SkipField() if callable(self.default): if getattr(self.default, 'requires_context', False): return self.default(serializer_field) else: return self.default() return self.default
def to_internal_value(self, data): if isinstance(data, six.string_types) and data.isdigit(): data = int(data) try: value = self.enum.get(data).value except AttributeError: # .get() returned None if not self.required: raise serializers.SkipField() self.fail("invalid_choice", input=data) return value
def to_internal_value(self, value): ''' This is a hack to do some pre-validation. The building of the GenericRelations must be done in the view itself b/c it needs access to the saved instance. ''' import json if value: try: entities = json.loads(value) except Exception: raise serializers.ValidationError('Error parsing JSON') for child in entities: try: overlay_type = child['overlay_type'] ids = child['ids'] except Exception: raise serializers.ValidationError( '%s must have an overlay_type and an ids attribute' % child) if not isinstance(ids, list): raise serializers.ValidationError('%s must be a list' % ids) for id in ids: # ensure that the requested child item exists: from localground.apps.site.models import Base try: obj = Base.get_model( model_name=overlay_type).objects.get(id=id) except Exception: raise serializers.ValidationError( 'No %s object exists with id=%s' % (overlay_type, id)) # this exception prevents the 'entities' dictionary from being # directly applied to the entities many-to-many (which is impossible) # to specify before the object has been created. raise serializers.SkipField()
def validate_empty_values(self, data): raise serializers.SkipField()
def __call__(self): if not self.is_update: raise serializers.SkipField() if callable(self.default): return self.default() return self.default
def to_internal_value(self, value): if getattr(self, 'encrypted', False) and isinstance( value, str) and value.startswith('$encrypted$'): raise serializers.SkipField() obj = super(SettingFieldMixin, self).to_internal_value(value) return super(SettingFieldMixin, self).to_representation(obj)
def inner_validate_method(self, value): if 'action' not in self.context: raise serializers.SkipField() return validate_method(self, value, self.context['action'])
def get_attribute(self, instance): raise serializers.SkipField()
def to_internal_value(self, data): if not isinstance(data, list): message = self.error_messages['not_a_list'].format(input_type=type(data).__name__) raise serializers.ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [message]}, code='not_a_list') if not self.allow_empty and len(data) == 0: if self.parent and self.partial: raise serializers.SkipField() else: self.fail('empty') ret = [] errors = [] partial = self.partial # build look-up objects for instances and data, so we can look them up with their keys try: known_instances = {(x.subname, x.type): x for x in self.instance} except TypeError: # in case self.instance is None (as during POST) known_instances = {} indices_by_key = {} for idx, item in enumerate(data): # Validate item type before using anything from it if not isinstance(item, dict): self.fail('invalid', datatype=type(item).__name__) items = indices_by_key.setdefault(self._key(item), set()) items.add(idx) # Iterate over all rows in the data given for idx, item in enumerate(data): try: # see if other rows have the same key if len(indices_by_key[self._key(item)]) > 1: raise serializers.ValidationError({ 'non_field_errors': [ 'Same subname and type as in position(s) %s, but must be unique.' % ', '.join(map(str, indices_by_key[self._key(item)] - {idx})) ] }) # determine if this is a partial update (i.e. PATCH): # we allow partial update if a partial update method (i.e. PATCH) is used, as indicated by self.partial, # and if this is not actually a create request because it is unknown and nonempty unknown = self._key(item) not in known_instances.keys() nonempty = item.get('records', None) != [] self.partial = partial and not (unknown and nonempty) self.child.instance = known_instances.get(self._key(item), None) # with partial value and instance in place, let the validation begin! validated = self.child.run_validation(item) except serializers.ValidationError as exc: errors.append(exc.detail) else: ret.append(validated) errors.append({}) self.partial = partial if any(errors): raise serializers.ValidationError(errors) return ret
def __call__(self): if self.is_many: raise serializers.SkipField() if callable(self.default): return self.default() return self.default
def to_internal_value(self, data): if not isinstance(data, list): message = self.error_messages['not_a_list'].format(input_type=type(data).__name__) raise serializers.ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [message]}, code='not_a_list') if not self.allow_empty and len(data) == 0: if self.parent and self.partial: raise serializers.SkipField() else: self.fail('empty') ret = [] errors = [] partial = self.partial # build look-up objects for instances and data, so we can look them up with their keys try: known_instances = {(x.subname, x.type): x for x in self.instance} except TypeError: # in case self.instance is None (as during POST) known_instances = {} indices = {} for idx, item in enumerate(data): # Validate item type before using anything from it if not isinstance(item, dict): self.fail('invalid', datatype=type(item).__name__) s, t = self._key(item) # subname, type # Construct an index of the RRsets in `data` by `s` and `t`. As (subname, type) may be given multiple times # (although invalid), we make indices[s][t] a set to properly keep track. We also check and record RRsets # which are known in the database (once per subname), using index `None` (for checking CNAME exclusivity). if s not in indices: types = self.child.domain.rrset_set.filter(subname=s).values_list('type', flat=True) indices[s] = {type_: {None} for type_ in types} items = indices[s].setdefault(t, set()) items.add(idx) collapsed_indices = copy.deepcopy(indices) for idx, item in enumerate(data): if item.get('records') == []: s, t = self._key(item) collapsed_indices[s][t] -= {idx, None} # Iterate over all rows in the data given for idx, item in enumerate(data): try: # see if other rows have the same key s, t = self._key(item) data_indices = indices[s][t] - {None} if len(data_indices) > 1: raise serializers.ValidationError({ 'non_field_errors': [ 'Same subname and type as in position(s) %s, but must be unique.' % ', '.join(map(str, data_indices - {idx})) ] }) # see if other rows violate CNAME exclusivity if item.get('records') != []: conflicting_indices_by_type = {k: v for k, v in collapsed_indices[s].items() if (k == 'CNAME') != (t == 'CNAME')} if any(conflicting_indices_by_type.values()): types_by_position = self._types_by_position_string(conflicting_indices_by_type) raise serializers.ValidationError({ 'non_field_errors': [ f'RRset with conflicting type present: {types_by_position}.' ' (No other RRsets are allowed alongside CNAME.)' ] }) # determine if this is a partial update (i.e. PATCH): # we allow partial update if a partial update method (i.e. PATCH) is used, as indicated by self.partial, # and if this is not actually a create request because it is unknown and nonempty unknown = self._key(item) not in known_instances.keys() nonempty = item.get('records', None) != [] self.partial = partial and not (unknown and nonempty) self.child.instance = known_instances.get(self._key(item), None) # with partial value and instance in place, let the validation begin! validated = self.child.run_validation(item) except serializers.ValidationError as exc: errors.append(exc.detail) else: ret.append(validated) errors.append({}) self.partial = partial if any(errors): raise serializers.ValidationError(errors) return ret
def get_attribute(self, instance): if self.source == 'payment.from_account' and instance.value < 0 \ or self.source == 'payment.to_account' and instance.value > 0: raise serializers.SkipField() return super().get_attribute(instance)