diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 3278cf51c..d39b187bc 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -263,6 +263,7 @@ class CreateOnlyDefault(object): def set_context(self, serializer_field): self.is_update = serializer_field.parent.instance is not None if callable(self.default) and hasattr(self.default, 'set_context') and not self.is_update: + self.default = copy.deepcopy(self.default) self.default.set_context(serializer_field) def __call__(self): @@ -487,6 +488,7 @@ class Field(object): raise SkipField() if callable(self.default): if hasattr(self.default, 'set_context'): + self.default = copy.deepcopy(self.default) self.default.set_context(self) return self.default() return self.default @@ -544,6 +546,7 @@ class Field(object): errors = [] for validator in self.validators: if hasattr(validator, 'set_context'): + validator = copy.deepcopy(validator) validator.set_context(self) try: diff --git a/tests/test_validators.py b/tests/test_validators.py index 4bbddb64b..73d3eb0d2 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -365,6 +365,28 @@ class TestUniquenessTogetherValidation(TestCase): validator.filter_queryset(attrs=data, queryset=queryset) assert queryset.called_with == {'race_name': 'bar', 'position': 1} + def test_validator_instances_with_context_are_not_used_twice(self): + """ + Every instance of a serializer should use unique instances of validators + when calling `set_context`. + """ + def data(): + return {'race_name': 'example', 'position': 3} + + def check_validators(serializer): + for validator in serializer.validators: + assert not hasattr(validator, 'instance') + + serializer = UniquenessTogetherSerializer(self.instance, data=data()) + check_validators(serializer) + serializer.run_validators({}) + check_validators(serializer) + + another_serializer = UniquenessTogetherSerializer(data=data()) + check_validators(another_serializer) + another_serializer.run_validators(data()) + check_validators(another_serializer) + # Tests for `UniqueForDateValidator` # ----------------------------------