diff --git a/rest_framework/fields.py b/rest_framework/fields.py index f582a6813..dd90c3f86 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -351,7 +351,12 @@ class RelatedField(WritableField): if self.read_only: return - value = data.get(field_name) + try: + value = data[field_name] + except KeyError: + if self.required: + raise ValidationError(self.error_messages['required']) + return if value in (None, '') and not self.null: raise ValidationError('Value may not be null') diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 6ea4b4246..f780e811e 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -308,6 +308,38 @@ class ModelValidationTests(TestCase): self.assertFalse(second_serializer.is_valid()) self.assertEqual(second_serializer.errors, {'title': [u'Album with this Title already exists.']}) + def test_foreign_key_with_partial(self): + """ + Test ModelSerializer validation with partial=True + + Specifically test foreign key validation. + """ + + album = Album(title='test') + album.save() + + class PhotoSerializer(serializers.ModelSerializer): + class Meta: + model = Photo + + photo_serializer = PhotoSerializer(data={'description': 'test', 'album': album.pk}) + self.assertTrue(photo_serializer.is_valid()) + photo = photo_serializer.save() + + # Updating only the album (foreign key) + photo_serializer = PhotoSerializer(instance=photo, data={'album': album.pk}, partial=True) + self.assertTrue(photo_serializer.is_valid()) + self.assertTrue(photo_serializer.save()) + + # Updating only the description + photo_serializer = PhotoSerializer(instance=photo, + data={'description': 'new'}, + partial=True) + + self.assertTrue(photo_serializer.is_valid()) + self.assertTrue(photo_serializer.save()) + + class RegexValidationTest(TestCase): def test_create_failed(self):