def is_partly_invalid(self):
""" Allows to have a multiple serializer (many=True) with part of the
raise serializers data valid and part of the data invalid.
"""
assert hasattr(self, 'initial_data'), (
'Cannot call `.is_partly_valid()`no `data=` keyword argument was'
'passed when instantiating the serializer instance.'
)
has_errors = False
# this one may trigger a ValidationError up to http client
self.run_list_size_validation(self.initial_data)
# those can't, from here, validation is always considered good
if not hasattr(self, '_validated_data'):
self._validated_data, exc = self.run_partial_validation(
self.initial_data)
self._partial_errors = exc.detail
if exc.detail:
has_errors = True
# partly valid if at least something is valid
return has_errors
python类ValidationError()的实例源码
def run_partial_validation(self, data=fields.empty):
"""
We override the default `run_validation`, because the validation
performed by validators and the `.validate()` method should
be coerced into an error dictionary with a 'non_fields_error' key.
"""
# Called 1 time for all the data list
# output of this function is set into self._validated_data by is_valid
(is_empty_value, data) = self.validate_empty_values(data)
if is_empty_value:
return data
value, error = self.to_internal_value_error(data)
try:
self.run_validators(value) # does nothing in our case
value = self.validate(value)
assert value is not None, \
'.validate() should return the validated data'
except (ValidationError, DjangoValidationError) as exc:
raise ValidationError(detail=get_validation_error_detail(exc))
return value, error
def validate_membership(self, attrs, source):
all_modified = attrs.get('membership')
all_existing = Member.objects.filter(
user=self.object, status=MemberStatusField.STATUS_MEMBER
)
all_existing = list(all_existing)
all_modified = list(all_modified)
for exi in all_existing:
found = False
for mod in all_modified:
if exi.id == mod.id:
found = True
if mod.status != MemberStatusField.STATUS_MEMBER:
msg = 'Only members with STATUS_MEMBER could be updated'
raise serializers.ValidationError(msg)
if not found:
msg = 'All memberships keys has to be changed at once'
raise serializers.ValidationError(msg)
return attrs
def validate(self, data):
name = data.get('name')
config = data.get('config', {})
if not name or name not in plugins:
raise serializers.ValidationError('Invalid plugin name')
plugin_schema = plugins[name]
if self.instance:
initial_config = self.instance.config
initial_config.update(config)
config = initial_config
try:
jsonschema.validate(config, plugin_schema)
except jsonschema.ValidationError as e:
raise serializers.ValidationError({'config': e})
plugin_validators = validators.validator_classes.get(name, [])
for validator in plugin_validators:
validate = validator(data['config'])
validate()
return data
def validate(self, data):
"""
Verify that only existing intances connected to the old fermentable id are present here.
The instances part of this data should only be used for removing certain fermentable
instances from the data.
"""
if 'instances' in data['new_fermentable']:
for instance_id in data['new_fermentable']['intances']:
instance = models.FermentableInstance.objects.get(pk=instance_id)
if instance is None:
raise serializers.ValidationError(str(instance_id) + " does not correspond to a FermentableInstance.")
if instance is not None:
if instance.fermentable.id != old_fermentable_id:
raise serializers.ValidationError(
"Instance with id '{0}' does not belong to the old fermentable with " \
"id '{1}'. New instances cannot be added with this endpoint. This " \
"should only be used for taking old instances out of the suggestion." \
.format(intance_id, data['old_fermentable_id']))
return super(FermentableSuggestion, self).validate(data)
def validate_moira_lists(lists):
"""
Raise a validation error if any of the moira lists in a list does not exist or is not a mailing list
Args:
lists(list of MoiraList): List of moira lists
Returns:
(list of MoiraList) List of moira lists
"""
bad_lists = []
moira_client = get_moira_client()
for mlist in lists:
if not moira_client.list_exists(mlist.name):
bad_lists.append(mlist.name)
else:
attributes = moira_client.client.service.getListAttributes(mlist.name, moira_client.proxy_id)
if not (attributes and attributes[0]['mailList']):
bad_lists.append(mlist.name)
if bad_lists:
raise serializers.ValidationError("Not found or not mailing list: {}".format(','.join(bad_lists)))
return lists
def validate(self, data):
"""
Validate visibility is not required for replies.
If given, make sure it is the same as parent. If not given, use parent visibility.
"""
parent = data.get("parent")
if parent:
if data.get("visibility") and parent.visibility != data.get("visibility"):
raise serializers.ValidationError("Visibility was given but it doesn't match parent.")
data["visibility"] = parent.visibility
else:
if not self.instance and not data.get("visibility"):
raise serializers.ValidationError("Visibility is required")
return data
def validate_parent(self, value):
# Validate parent cannot be changed
if self.instance and value != self.instance.parent:
raise serializers.ValidationError("Parent cannot be changed for an existing Content instance.")
# Validate user can see parent
if not self.instance and value:
request = self.context.get("request")
if not value.visible_for_user(request.user):
raise serializers.ValidationError("Parent not found")
return value
def validate_username(self, username):
if User.objects.filter(username=username).exists():
raise serializers.ValidationError('Username already exist')
return username
def validate(self, data):
if data['password1'] != data['password2']:
raise serializers.ValidationError('Passwords didn\'t match')
return data
def validate(self, data):
if data['name'] != data['name'].replace(" ", "").lower():
raise serializers.ValidationError(config.KEYWORD_NOT_ALLOWED)
return data
def validate(self, data):
# To handle cases creation, update and partial update
pizza = data.get('pizza', getattr(self.instance, 'pizza', None))
size = data.get('size', getattr(self.instance, 'size', None))
if size not in pizza.sizes:
raise serializers.ValidationError(_('You should provide valid size for your pizza'))
return data
def __call__(self, value):
if value > self.high or value < self.low:
raise serializers.ValidationError("value must be between %d and %d (inclusive)" % (self.low, self.high))
##########################################################################
## Serializers
##########################################################################
def test_in_range_validator(self):
"""
Test the in-range validator
"""
validator = InRange(-1, 1)
self.assertRaises(serializers.ValidationError, validator, -2)
self.assertRaises(serializers.ValidationError, validator, 2)
self.assertNotRaises(serializers.ValidationError, validator, -1)
self.assertNotRaises(serializers.ValidationError, validator, 1)
self.assertNotRaises(serializers.ValidationError, validator, 0)
def validate(self, attrs):
if attrs['password'] != attrs['repeated']:
raise serializers.ValidationError("passwords do not match!")
return attrs
def __call__(self, value):
if len(value) > self.limit:
raise serializers.ValidationError(
"Cannot add more than {} {}!".format(self.limit, self.things)
)
##########################################################################
## Serializers
##########################################################################
def create(self, validated_data):
zone = Zone.objects.create(**validated_data)
try:
zone.r53_zone.create()
except ClientError as e:
raise serializers.ValidationError(detail=str(e))
return zone
def validate(self, attrs):
alias = attrs.get(self.alias_type)
if alias:
# Create or authenticate a user
# Return THem
if api_settings.PASSWORDLESS_REGISTER_NEW_USERS is True:
# If new aliases should register new users.
user, created = User.objects.get_or_create(**{self.alias_type: alias})
else:
# If new aliases should not register new users.
try:
user = User.objects.get(**{self.alias_type: alias})
except User.DoesNotExist:
user = None
if user:
if not user.is_active:
# If valid, return attrs so we can create a token in our logic controller
msg = _('User account is disabled.')
raise serializers.ValidationError(msg)
else:
msg = _('No account is associated with this alias.')
raise serializers.ValidationError(msg)
else:
msg = _('Missing %s.') % self.alias_type
raise serializers.ValidationError(msg)
attrs['user'] = user
return attrs
def validate(self, attrs):
msg = _('There was a problem with your request.')
if self.alias_type:
# Get request.user
# Get their specified valid endpoint
# Validate
request = self.context["request"]
if request and hasattr(request, "user"):
user = request.user
if user:
if not user.is_active:
# If valid, return attrs so we can create a token in our logic controller
msg = _('User account is disabled.')
else:
if hasattr(user, self.alias_type):
# Has the appropriate alias type
attrs['user'] = user
return attrs
else:
msg = _('This user doesn\'t have an %s.' % self.alias_type)
raise serializers.ValidationError(msg)
else:
msg = _('Missing %s.') % self.alias_type
raise serializers.ValidationError(msg)
def token_age_validator(value):
"""
Check token age
Makes sure a token is within the proper expiration datetime window.
"""
valid_token = validate_token_age(value)
if not valid_token:
raise serializers.ValidationError("The token you entered isn't valid.")
return value