diff --git a/rest_framework/fields.py b/rest_framework/fields.py index a336528e8..b91e1f2c1 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -534,8 +534,21 @@ class Field(object): if hasattr(validator, 'set_context'): validator.set_context(self) + # Add missing fields to `value` for partial update if these fields exists in validator, but missing in + # `value` + value_ext = copy.copy(value) + if getattr(self.root, 'partial', False): + if hasattr(validator, 'date_field') and validator.date_field not in value_ext: + value_ext[validator.date_field] = \ + self.fields.fields.get(validator.date_field).to_internal_value( + getattr(self.instance, validator.date_field)) + if hasattr(validator, 'field') and validator.field not in value_ext: + value_ext[validator.field] = \ + self.fields.fields.get(validator.field).to_internal_value( + getattr(self.instance, validator.field)) + try: - validator(value) + validator(value_ext) except ValidationError as exc: # If the validation error contains a mapping of fields to # errors then simply raise it immediately rather than diff --git a/tests/test_validators.py b/tests/test_validators.py index 62126ddb3..a10f5a000 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -348,6 +348,7 @@ class TestUniquenessTogetherValidation(TestCase): class UniqueForDateModel(models.Model): slug = models.CharField(max_length=100, unique_for_date='published') published = models.DateField() + body = models.CharField(max_length=100, null=True) class UniqueForDateSerializer(serializers.ModelSerializer): @@ -360,7 +361,8 @@ class TestUniquenessForDateValidation(TestCase): def setUp(self): self.instance = UniqueForDateModel.objects.create( slug='existing', - published='2000-01-01' + published='2000-01-01', + body='some body' ) def test_repr(self): @@ -370,6 +372,7 @@ class TestUniquenessForDateValidation(TestCase): id = IntegerField(label='ID', read_only=True) slug = CharField(max_length=100) published = DateField(required=True) + body = CharField(allow_null=True, max_length=100, required=False) class Meta: validators = [] """) @@ -411,6 +414,28 @@ class TestUniquenessForDateValidation(TestCase): 'published': datetime.date(2000, 1, 1) } + def test_missing_date_field_in_partial_update(self): + """ + When performing partial update if `date_field` is missed it takes its current value + """ + data = {'slug': 'existing2'} + serializer = UniqueForDateSerializer(instance=self.instance, data=data, partial=True) + assert serializer.is_valid() + assert serializer.validated_data == { + 'slug': 'existing2' + } + + def test_missing_field_in_partial_update(self): + """ + When performing partial update if `field` is missed it takes its current value + """ + data = {'body': 'new body'} + serializer = UniqueForDateSerializer(instance=self.instance, data=data, partial=True) + assert serializer.is_valid() + assert serializer.validated_data == { + 'body': 'new body' + } + # Tests for `UniqueForMonthValidator` # ----------------------------------