Skip to content

Commit

Permalink
Alter read_only+default behaviour (#5886)
Browse files Browse the repository at this point in the history
* Always exclude read_only fields from _writable_fields

* Remove `read_only` from `CreateOnlyDefault` example.
      In this context (without mentioning `save`) now slightly misleading.
  • Loading branch information
carltongibson committed Mar 20, 2018
1 parent 12569f8 commit c2b24f8
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 5 deletions.
1 change: 0 additions & 1 deletion docs/api-guide/validators.md
Expand Up @@ -189,7 +189,6 @@ A default class that can be used to *only set a default argument during create o
It takes a single argument, which is the default value or callable that should be used during create operations.

created_at = serializers.DateTimeField(
read_only=True,
default=serializers.CreateOnlyDefault(timezone.now)
)

Expand Down
3 changes: 1 addition & 2 deletions rest_framework/serializers.py
Expand Up @@ -367,8 +367,7 @@ def fields(self):
@cached_property
def _writable_fields(self):
return [
field for field in self.fields.values()
if (not field.read_only) or (field.default is not empty)
field for field in self.fields.values() if not field.read_only
]

@cached_property
Expand Down
9 changes: 8 additions & 1 deletion tests/test_fields.py
Expand Up @@ -219,10 +219,17 @@ def example_callable(self):
class TestReadOnly:
def setup(self):
class TestSerializer(serializers.Serializer):
read_only = serializers.ReadOnlyField()
read_only = serializers.ReadOnlyField(default="789")
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(serializer._writable_fields) == 1

def test_validate_read_only(self):
"""
Read-only serializers.should not be included in validation.
Expand Down
2 changes: 1 addition & 1 deletion tests/test_serializer.py
Expand Up @@ -513,7 +513,7 @@ class ExampleSerializer(serializers.Serializer):
class TestDefaultInclusions:
def setup(self):
class ExampleSerializer(serializers.Serializer):
char = serializers.CharField(read_only=True, default='abc')
char = serializers.CharField(default='abc')
integer = serializers.IntegerField()
self.Serializer = ExampleSerializer

Expand Down

0 comments on commit c2b24f8

Please sign in to comment.