Allow setting read_only fields from defaults

According to the documentation, this is supposed to work, but it doesn't. Add the read_only default values after the validation runs so they actually get saved.
This commit is contained in:
Bob Thomas 2021-04-01 17:03:20 -04:00
parent 78da1a824f
commit a0a27a19a9
3 changed files with 45 additions and 0 deletions

View File

@ -488,6 +488,7 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
if errors:
raise ValidationError(errors)
ret.update(self._read_only_defaults())
return ret
def to_representation(self, instance):

View File

@ -1333,3 +1333,18 @@ class Issue6751Test(TestCase):
serializer.save()
self.assertEqual(instance.char_field, 'value changed by signal')
class TestReadonlyDefault(TestCase):
def test_readonly_default(self):
class TestSerializer(serializers.ModelSerializer):
char_field = serializers.CharField(read_only=True, default='default')
class Meta:
model = OneFieldModel
fields = ('char_field',)
serializer = TestSerializer(data={})
serializer.is_valid()
instance = serializer.save()
assert instance.char_field == 'default'

View File

@ -306,6 +306,35 @@ class TestNestedWriteErrors(TestCase):
)
class TestNestedWriteReadonlyDefault(TestCase):
def test_nested_serializer_readonly_default(self):
profile_obj = NestedWriteProfile.objects.create(address='52 festive road')
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = NestedWriteProfile
fields = ['address']
class NestedProfileSerializer(serializers.ModelSerializer):
profile = ProfileSerializer(read_only=True, default=lambda: profile_obj)
class Meta:
model = NestedWritePerson
fields = ['profile']
serializer = NestedProfileSerializer(data={})
assert serializer.is_valid()
assert serializer.validated_data == {'profile': profile_obj}
nested = serializer.save()
assert nested.profile == profile_obj
serializer = NestedProfileSerializer(data={'profile': {'address': '123 fake street'}})
assert serializer.is_valid()
assert serializer.validated_data == {'profile': profile_obj}
serializer.save()
assert nested.profile == profile_obj
if postgres_fields:
class NonRelationalPersonModel(models.Model):
"""Model declaring a postgres JSONField"""