Skip to content

Commit 5144316

Browse files
Merge pull request #3431 from paolopaolopaolo/issue-3265
Guard against calling `serializer.data` before `serializer.save()`
2 parents 7661398 + 7640bfe commit 5144316

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

rest_framework/serializers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ def save(self, **kwargs):
166166
"For example: 'serializer.save(owner=request.user)'.'"
167167
)
168168

169+
assert not hasattr(self, '_data'), (
170+
"You cannot call `.save()` after accessing `serializer.data`."
171+
"If you need to access data before committing to the database then "
172+
"inspect 'serializer.validated_data' instead. "
173+
)
174+
169175
validated_data = dict(
170176
list(self.validated_data.items()) +
171177
list(kwargs.items())

tests/test_serializer.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ class MissingAttributes:
5151
with pytest.raises(AttributeError):
5252
serializer.data
5353

54+
def test_data_access_before_save_raises_error(self):
55+
def create(validated_data):
56+
return validated_data
57+
serializer = self.Serializer(data={'char': 'abc', 'integer': 123})
58+
serializer.create = create
59+
assert serializer.is_valid()
60+
assert serializer.data == {'char': 'abc', 'integer': 123}
61+
with pytest.raises(AssertionError):
62+
serializer.save()
63+
5464

5565
class TestValidateMethod:
5666
def test_non_field_error_validate_method(self):

0 commit comments

Comments
 (0)