diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 73ac6bc2a..8d25c328d 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -1088,6 +1088,9 @@ class ModelSerializer(Serializer): if extra_kwargs.get('default') and kwargs.get('required') is False: kwargs.pop('required') + if kwargs.get('read_only', False): + extra_kwargs.pop('required', None) + kwargs.update(extra_kwargs) return kwargs diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index dc34649ea..49ad8ac10 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -316,6 +316,14 @@ class RelationalModel(models.Model): through = models.ManyToManyField(ThroughTargetModel, through=Supplementary, related_name='reverse_through') +class UniqueTogetherModel(models.Model): + foreign_key = models.ForeignKey(ForeignKeyTargetModel, related_name='unique_foreign_key') + one_to_one = models.OneToOneField(OneToOneTargetModel, related_name='unique_one_to_one') + + class Meta: + unique_together = ("foreign_key", "one_to_one") + + class TestRelationalFieldMappings(TestCase): def test_pk_relations(self): class TestSerializer(serializers.ModelSerializer): @@ -395,6 +403,32 @@ class TestRelationalFieldMappings(TestCase): """) self.assertEqual(unicode_repr(TestSerializer()), expected) + def test_nested_unique_together_relations(self): + class TestSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = UniqueTogetherModel + depth = 1 + expected = dedent(""" + TestSerializer(): + url = HyperlinkedIdentityField(view_name='uniquetogethermodel-detail') + foreign_key = NestedSerializer(read_only=True): + url = HyperlinkedIdentityField(view_name='foreignkeytargetmodel-detail') + name = CharField(max_length=100) + 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 + # and py3. (See above) + expected = expected.replace( + "('foreign_key', 'one_to_one')", + "(u'foreign_key', u'one_to_one')" + ) + self.assertEqual(unicode_repr(TestSerializer()), expected) + def test_pk_reverse_foreign_key(self): class TestSerializer(serializers.ModelSerializer): class Meta: