diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 107115a2f..e49c0e71d 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -361,18 +361,6 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass): field.bind(field_name=field_name, parent=self) return fields - @property - def _writable_fields(self): - for field in self.fields.values(): - if not field.read_only: - yield field - - @property - def _readable_fields(self): - for field in self.fields.values(): - if not field.write_only: - yield field - def get_fields(self): """ Returns a dictionary of {field_name: field_instance}. @@ -478,9 +466,11 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass): ret = OrderedDict() errors = OrderedDict() - fields = self._writable_fields - for field in fields: + for field in self.fields.values(): + if field.read_only: + continue + validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = field.get_value(data) try: @@ -506,9 +496,11 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass): Object instance -> Dict of primitive datatypes. """ ret = OrderedDict() - fields = self._readable_fields - for field in fields: + for field in self.fields.values(): + if field.write_only: + continue + try: attribute = field.get_attribute(instance) except SkipField: @@ -808,7 +800,8 @@ def raise_errors_on_nested_writes(method_name, serializer, validated_data): isinstance(field, BaseSerializer) and (field.source in validated_data) and isinstance(validated_data[field.source], (list, dict)) - for field in serializer._writable_fields + for field in serializer.fields.values() + if not field.read_only ), ( 'The `.{method_name}()` method does not support writable nested ' 'fields by default.\nWrite an explicit `.{method_name}()` method for ' @@ -1498,8 +1491,8 @@ class ModelSerializer(Serializer): # cannot map to a field, and must be a traversal, so we're not # including those. field_names = { - field.source for field in self._writable_fields - if (field.source != '*') and ('.' not in field.source) + field.source for field in self.fields.values() + if not field.read_only and field.source != '*' and '.' not in field.source } # Special Case: Add read_only fields with defaults. diff --git a/tests/test_fields.py b/tests/test_fields.py index 6a6d88d03..6371f60d5 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -214,13 +214,6 @@ class TestReadOnly: writable = serializers.IntegerField() self.Serializer = TestSerializer - def test_writable_fields(self): - """ - Read-only fields should not be writable, even with default () - """ - serializer = self.Serializer() - assert len(list(serializer._writable_fields)) == 1 - def test_validate_read_only(self): """ Read-only serializers.should not be included in validation.