mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-08 06:14:47 +03:00
Error on undefined
Provides the ability to return validation errors for fields supplied to a serializer that have not been defined on the serializer. resolves #2635
This commit is contained in:
parent
5570db402f
commit
efcf9766c6
|
@ -570,6 +570,29 @@ This option is a dictionary, mapping field names to a dictionary of keyword argu
|
||||||
user.save()
|
user.save()
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
## Return errors on undefined fields
|
||||||
|
|
||||||
|
By default, if the user consuming the your API supplies fields in a payload that you have not defined (eg. fields in a POST payload), Django Rest Framework will ignore them.
|
||||||
|
|
||||||
|
It is possible to have DRF return validation errors for undefined fields supplied by the user. This is done by setting `error_on_undefined=True` in your Meta class. For example:
|
||||||
|
|
||||||
|
class NameSerializer(serializers.Serializer):
|
||||||
|
first_name = serializers.CharField()
|
||||||
|
last_name = serializers.Charfield()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
error_on_undefined = True
|
||||||
|
|
||||||
|
serializer = NameSerializer(data={'first_name': 'George'
|
||||||
|
'middle_name': 'Walker',
|
||||||
|
'last_name': 'Bush'})
|
||||||
|
serializer.is_valid() # False
|
||||||
|
print(serializer.errors) # {'middle_name': 'Not a supported field.'}
|
||||||
|
|
||||||
|
This can be helpful to users of your API as they may not realise that they are supplying an unsupported field. For example they may have a typo in their integration code.
|
||||||
|
|
||||||
|
|
||||||
## Relational fields
|
## Relational fields
|
||||||
|
|
||||||
When serializing model instances, there are a number of different ways you might choose to represent relationships. The default representation for `ModelSerializer` is to use the primary keys of the related instances.
|
When serializing model instances, there are a number of different ways you might choose to represent relationships. The default representation for `ModelSerializer` is to use the primary keys of the related instances.
|
||||||
|
|
|
@ -323,7 +323,8 @@ def get_validation_error_detail(exc):
|
||||||
@six.add_metaclass(SerializerMetaclass)
|
@six.add_metaclass(SerializerMetaclass)
|
||||||
class Serializer(BaseSerializer):
|
class Serializer(BaseSerializer):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _('Invalid data. Expected a dictionary, but got {datatype}.')
|
'invalid': _('Invalid data. Expected a dictionary, but got {datatype}.'),
|
||||||
|
'undefined': _('Not a supported field.')
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -446,6 +447,13 @@ class Serializer(BaseSerializer):
|
||||||
else:
|
else:
|
||||||
set_value(ret, field.source_attrs, validated_value)
|
set_value(ret, field.source_attrs, validated_value)
|
||||||
|
|
||||||
|
if getattr(self, 'Meta', None) and \
|
||||||
|
getattr(self.Meta, 'error_on_undefined', False):
|
||||||
|
undefined_fields = set(data) - set(self.fields)
|
||||||
|
if undefined_fields:
|
||||||
|
errors.update({field: self.error_messages['undefined']
|
||||||
|
for field in undefined_fields})
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
raise ValidationError(errors)
|
raise ValidationError(errors)
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,18 @@ class TestSerializer:
|
||||||
with pytest.raises(AssertionError):
|
with pytest.raises(AssertionError):
|
||||||
serializer.save()
|
serializer.save()
|
||||||
|
|
||||||
|
def test_error_on_undefined(self):
|
||||||
|
class ExampleSerializer(serializers.Serializer):
|
||||||
|
char = serializers.CharField()
|
||||||
|
|
||||||
|
class Meta():
|
||||||
|
error_on_undefined = True
|
||||||
|
|
||||||
|
serializer = ExampleSerializer(data={'char': 'abc', 'foo': 'bar'})
|
||||||
|
assert not serializer.is_valid()
|
||||||
|
assert serializer.validated_data == {}
|
||||||
|
assert serializer.errors == {'foo': 'Not a supported field.'}
|
||||||
|
|
||||||
|
|
||||||
class TestValidateMethod:
|
class TestValidateMethod:
|
||||||
def test_non_field_error_validate_method(self):
|
def test_non_field_error_validate_method(self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user