diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index a80fc7996..e4432833c 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -13,7 +13,7 @@ response content is handled by parsers and renderers. import copy import inspect import traceback -from collections import OrderedDict, defaultdict +from collections import ChainMap, OrderedDict, defaultdict from collections.abc import Mapping from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured @@ -215,12 +215,17 @@ class BaseSerializer(Field): 'passed when instantiating the serializer instance.' ) - if not hasattr(self, '_validated_data'): - validation_data = self.to_representation(self.instance) if self.instance else {} - validation_data.update(self.initial_data) - + if not hasattr(self, '_validated_data'): + if self.instance and getattr(getattr(self, 'Meta', None), 'validate_entire_instance', api_settings.VALIDATE_ENTIRE_INSTANCE): + data = ChainMap( + self.initial_data, + self.to_representation(self.instance) + ) + else: + data = self.initial_data + try: - self._validated_data = self.run_validation(validation_data) + self._validated_data = self.run_validation(data) except ValidationError as exc: self._validated_data = {} self._errors = exc.detail diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 9eb4c5653..87badbad9 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -124,6 +124,9 @@ DEFAULTS = { 'retrieve': 'read', 'destroy': 'delete' }, + + # Validation + 'VALIDATE_ENTIRE_INSTANCE': False, } diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index 38a9f36cc..e9d4bb06e 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -1348,6 +1348,7 @@ class Issue7489Serializer(serializers.ModelSerializer): class Meta: model = Issue7489Model fields = '__all__' + validate_entire_instance = True class Issue7489Test(TestCase):