This commit is contained in:
Alex Hutton 2016-05-22 15:23:02 +00:00
commit 55ac1d1ef4
3 changed files with 44 additions and 1 deletions

View File

@ -570,6 +570,29 @@ This option is a dictionary, mapping field names to a dictionary of keyword argu
user.save()
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
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.

View File

@ -323,7 +323,8 @@ def get_validation_error_detail(exc):
@six.add_metaclass(SerializerMetaclass)
class Serializer(BaseSerializer):
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
@ -446,6 +447,13 @@ class Serializer(BaseSerializer):
else:
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:
raise ValidationError(errors)

View File

@ -61,6 +61,18 @@ class TestSerializer:
with pytest.raises(AssertionError):
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:
def test_non_field_error_validate_method(self):