diff --git a/rest_framework/validators.py b/rest_framework/validators.py index a21f67e60e..83ad6f7d8e 100644 --- a/rest_framework/validators.py +++ b/rest_framework/validators.py @@ -35,7 +35,7 @@ def set_context(self, serializer_field): """ # Determine the underlying model field name. This may not be the # same as the serializer field name if `source=<>` is set. - self.field_name = serializer_field.source_attrs[0] + self.field_name = serializer_field.source_attrs[-1] # Determine the existing instance, if this is an update operation. self.instance = getattr(serializer_field.parent, 'instance', None) @@ -174,8 +174,8 @@ def set_context(self, serializer): """ # Determine the underlying model field names. These may not be the # same as the serializer field names if `source=<>` is set. - self.field_name = serializer.fields[self.field].source_attrs[0] - self.date_field_name = serializer.fields[self.date_field].source_attrs[0] + self.field_name = serializer.fields[self.field].source_attrs[-1] + self.date_field_name = serializer.fields[self.date_field].source_attrs[-1] # Determine the existing instance, if this is an update operation. self.instance = getattr(serializer, 'instance', None) diff --git a/tests/test_validators.py b/tests/test_validators.py index acaaf57432..67156f31c7 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -4,6 +4,7 @@ from django.test import TestCase from rest_framework import serializers +from rest_framework.validators import UniqueValidator def dedent(blocktext): @@ -22,6 +23,20 @@ class Meta: model = UniquenessModel +class RelatedModel(models.Model): + user = models.OneToOneField(UniquenessModel, on_delete=models.CASCADE) + email = models.CharField(unique=True, max_length=80) + + +class RelatedModelSerializer(serializers.ModelSerializer): + username = serializers.CharField(source='user.username', + validators=[UniqueValidator(queryset=UniquenessModel.objects.all())]) # NOQA + + class Meta: + model = RelatedModel + fields = ('username', 'email') + + class AnotherUniquenessModel(models.Model): code = models.IntegerField(unique=True) @@ -73,6 +88,16 @@ def test_doesnt_pollute_model(self): self.assertEqual( AnotherUniquenessModel._meta.get_field('code').validators, []) + def test_related_model_is_unique(self): + data = {'username': 'existing', 'email': 'new-email@example.com'} + rs = RelatedModelSerializer(data=data) + self.assertFalse(rs.is_valid()) + self.assertEqual(rs.errors, + {'username': ['This field must be unique.']}) + data = {'username': 'new-username', 'email': 'new-email@example.com'} + rs = RelatedModelSerializer(data=data) + self.assertTrue(rs.is_valid()) + # Tests for `UniqueTogetherValidator` # -----------------------------------
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: