From 3812f63fcd73a6379143782a550969bf6873f8c8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 13 Jun 2016 11:59:31 +0100 Subject: [PATCH] Exclude read_only=True fields from unique_together validation --- rest_framework/serializers.py | 6 ++++++ tests/test_model_serializer.py | 2 -- tests/test_validators.py | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 3ec55724d..51676c513 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -1243,6 +1243,11 @@ class ModelSerializer(Serializer): read_only_fields = getattr(self.Meta, 'read_only_fields', None) if read_only_fields is not None: + if not isinstance(read_only_fields, (list, tuple)): + raise TypeError( + 'The `read_only_fields` option must be a list or tuple. ' + 'Got %s.' % type(read_only_fields).__name__ + ) for field_name in read_only_fields: kwargs = extra_kwargs.get(field_name, {}) kwargs['read_only'] = True @@ -1390,6 +1395,7 @@ class ModelSerializer(Serializer): field_names = { field.source for field in self.fields.values() if (field.source != '*') and ('.' not in field.source) + and not field.read_only } # Note that we make sure to check `unique_together` both on the diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index c6f7472aa..096cbc8d6 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -521,8 +521,6 @@ class TestRelationalFieldMappings(TestCase): one_to_one = NestedSerializer(read_only=True): url = HyperlinkedIdentityField(view_name='onetoonetargetmodel-detail') name = CharField(max_length=100) - class Meta: - validators = [] """) if six.PY2: # This case is also too awkward to resolve fully across both py2 diff --git a/tests/test_validators.py b/tests/test_validators.py index 9b388951e..e179cb3f4 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -239,6 +239,26 @@ class TestUniquenessTogetherValidation(TestCase): """) assert repr(serializer) == expected + def test_ignore_read_only_fields(self): + """ + When serializer fields are read only, then uniqueness + validators should not be added for that field. + """ + class ReadOnlyFieldSerializer(serializers.ModelSerializer): + class Meta: + model = UniquenessTogetherModel + fields = ('id', 'race_name', 'position') + read_only_fields = ('race_name',) + + serializer = ReadOnlyFieldSerializer() + expected = dedent(""" + ReadOnlyFieldSerializer(): + id = IntegerField(label='ID', read_only=True) + race_name = CharField(read_only=True) + position = IntegerField(required=True) + """) + assert repr(serializer) == expected + def test_ignore_validation_for_null_fields(self): # None values that are on fields which are part of the uniqueness # constraint cause the instance to ignore uniqueness validation.