diff options
| author | Ian Strachan | 2012-10-22 22:24:26 +0100 |
|---|---|---|
| committer | Ian Strachan | 2012-10-22 22:24:26 +0100 |
| commit | c7a0d52fd7e22fbc4a01ff900bd3b2c1215e984d (patch) | |
| tree | 164bc17f49ff80155edf846e94855369b8228878 /rest_framework | |
| parent | aba0172f5c988af145113678fe3d4f411111d4ff (diff) | |
| download | django-rest-framework-c7a0d52fd7e22fbc4a01ff900bd3b2c1215e984d.tar.bz2 | |
#314 Fix for manytomany field being required in the payload even though the field is specified as readonly in the serializer
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/fields.py | 3 | ||||
| -rw-r--r-- | rest_framework/tests/models.py | 5 | ||||
| -rw-r--r-- | rest_framework/tests/serializer.py | 54 |
3 files changed, 62 insertions, 0 deletions
diff --git a/rest_framework/fields.py b/rest_framework/fields.py index f610d6aa..6ed37823 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -256,6 +256,9 @@ class ManyRelatedMixin(object): return [self.to_native(item) for item in value.all()] def field_from_native(self, data, field_name, into): + if self.readonly: + return + try: # Form data value = data.getlist(self.source or field_name) diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index 8e721737..97cd0849 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -62,7 +62,12 @@ class CallableDefaultValueModel(RESTFrameworkModel): class ManyToManyModel(RESTFrameworkModel): rel = models.ManyToManyField(Anchor) + +class ReadOnlyManyToManyModel(RESTFrameworkModel): + text = models.CharField(max_length=100, default='anchor') + rel = models.ManyToManyField(Anchor) + # Models to test generic relations diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 2dfc04e1..c614b66a 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -246,6 +246,60 @@ class ManyToManyTests(TestCase): self.assertEquals(len(ManyToManyModel.objects.all()), 2) self.assertEquals(instance.pk, 2) self.assertEquals(list(instance.rel.all()), []) + +class ReadOnlyManyToManyTests(TestCase): + def setUp(self): + class ReadOnlyManyToManySerializer(serializers.ModelSerializer): + rel = serializers.ManyRelatedField(readonly=True) + class Meta: + model = ReadOnlyManyToManyModel + + self.serializer_class = ReadOnlyManyToManySerializer + + # An anchor instance to use for the relationship + self.anchor = Anchor() + self.anchor.save() + + # A model instance with a many to many relationship to the anchor + self.instance = ReadOnlyManyToManyModel() + self.instance.save() + self.instance.rel.add(self.anchor) + + # A serialized representation of the model instance + self.data = {'rel': [self.anchor.id], 'id': 1, 'text': 'anchor'} + + + def test_update(self): + """ + Attempt to update an instance of a model with a ManyToMany + relationship. Not updated due to readonly=True + """ + new_anchor = Anchor() + new_anchor.save() + data = {'rel': [self.anchor.id, new_anchor.id]} + serializer = self.serializer_class(data, instance=self.instance) + self.assertEquals(serializer.is_valid(), True) + instance = serializer.save() + self.assertEquals(len(ReadOnlyManyToManyModel.objects.all()), 1) + self.assertEquals(instance.pk, 1) + # rel is still as original (1 entry) + self.assertEquals(list(instance.rel.all()), [self.anchor]) + + def test_update_without_relationship(self): + """ + Attempt to update an instance of a model where many to ManyToMany + relationship is not supplied. Not updated due to readonly=True + """ + new_anchor = Anchor() + new_anchor.save() + data = {} + serializer = self.serializer_class(data, instance=self.instance) + self.assertEquals(serializer.is_valid(), True) + instance = serializer.save() + self.assertEquals(len(ReadOnlyManyToManyModel.objects.all()), 1) + self.assertEquals(instance.pk, 1) + # rel is still as original (1 entry) + self.assertEquals(list(instance.rel.all()), [self.anchor]) class DefaultValueTests(TestCase): |
