diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 01cf5ae3d..d35e918cd 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -148,7 +148,7 @@ class WritableField(Field): self.widget = widget def validate(self, value): - if value in validators.EMPTY_VALUES and self.required: + if value in validators.EMPTY_VALUES and self.required and not self.root.partial: raise ValidationError(self.error_messages['required']) def run_validators(self, value): @@ -186,7 +186,7 @@ class WritableField(Field): if self.default is not None: native = self.default else: - if self.required: + if self.required and not self.root.partial: raise ValidationError(self.error_messages['required']) return diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 2e7e2cf5d..229c1b2cd 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -91,12 +91,13 @@ class BaseSerializer(Field): _options_class = SerializerOptions _dict_class = SortedDictWithMetadata # Set to unsorted dict for backwards compatibility with unsorted implementations. - def __init__(self, instance=None, data=None, files=None, context=None, **kwargs): + def __init__(self, instance=None, data=None, files=None, context=None, partial=False, **kwargs): super(BaseSerializer, self).__init__(**kwargs) self.opts = self._options_class(self.Meta) self.fields = copy.deepcopy(self.base_fields) self.parent = None self.root = None + self.partial = partial self.context = context or {} diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index d522ef972..882f769c0 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -108,6 +108,18 @@ class BasicTests(TestCase): self.assertTrue(serializer.object is expected) self.assertEquals(serializer.data['sub_comment'], 'And Merry Christmas!') + def test_partial_update(self): + msg = 'Merry New Year!' + partial_data = {'content': msg} + serializer = CommentSerializer(self.comment, data=partial_data) + self.assertEquals(serializer.is_valid(), False) + serializer = CommentSerializer(self.comment, data=partial_data, partial=True) + expected = self.comment + self.assertEqual(serializer.is_valid(), True) + self.assertEquals(serializer.object, expected) + self.assertTrue(serializer.object is expected) + self.assertEquals(serializer.data['content'], msg) + def test_model_fields_as_expected(self): """ Make sure that the fields returned are the same as defined