Repository: encode/django-rest-framework

Issue:
SerializerMethodField issue after "unique together validator" fix
DRF version 3.16.0

After the "Fix unique together validator doesn't respect condition's fields (https://github.com/encode/django-rest-framework/pull/9360)" merge, a SerializerMethodField named as the same of a model field goes into the [HiddenField](https://github.com/encode/django-rest-framework/blob/c0202a0aa5cbaf8573458b932878dfd5044c93ab/rest_framework/serializers.py#L1511) because of the [unique_constraint_field is null](https://github.com/encode/django-rest-framework/blob/c0202a0aa5cbaf8573458b932878dfd5044c93ab/rest_framework/serializers.py#L1497)

model.py (part)
```python
class Repository(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)

    prefix = models.ForeignKey(
        "RepositoryPrefix",
        related_name="repository_set",
        on_delete=CASCADE,
        blank=False,
        null=True
    )
    ...
    
    class Meta:
        unique_together = [("prefix", "name")]
        ...
```

serializer.py
```python
class RepositorySerializer(serializers.ModelSerializer):
    prefix = serializers.SerializerMethodField()
    ...

    def get_prefix(self, obj):
        return obj.prefix.name if obj.prefix else None
```


Discussion:
DRF version 3.15.2 works fine
@kalekseev would you mind taking a look, please?



Patch:
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 0b87aa8fc1..8fe284bc84 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -1469,12 +1469,13 @@ def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs
                                         model_field.unique_for_year}
 
         unique_constraint_names -= {None}
+        model_fields_names = set(model_fields.keys())
 
         # Include each of the `unique_together` and `UniqueConstraint` field names,
         # so long as all the field names are included on the serializer.
         for unique_together_list, queryset, condition_fields, condition in self.get_unique_together_constraints(model):
             unique_together_list_and_condition_fields = set(unique_together_list) | set(condition_fields)
-            if set(field_names).issuperset(unique_together_list_and_condition_fields):
+            if model_fields_names.issuperset(unique_together_list_and_condition_fields):
                 unique_constraint_names |= unique_together_list_and_condition_fields
 
         # Now we have all the field names that have uniqueness constraints


Test patch:
diff --git a/tests/test_validators.py b/tests/test_validators.py
index d19734d98c..c594eecbe5 100644
--- a/tests/test_validators.py
+++ b/tests/test_validators.py
@@ -516,6 +516,43 @@ def filter(self, **kwargs):
         validator.filter_queryset(attrs=data, queryset=queryset, serializer=serializer)
         assert queryset.called_with == {'race_name': 'bar', 'position': 1}
 
+    def test_uniq_together_validation_uses_model_fields_method_field(self):
+        class TestSerializer(serializers.ModelSerializer):
+            position = serializers.SerializerMethodField()
+
+            def get_position(self, obj):
+                return obj.position or 0
+
+            class Meta:
+                model = NullUniquenessTogetherModel
+                fields = ['race_name', 'position']
+
+        serializer = TestSerializer()
+        expected = dedent("""
+            TestSerializer():
+                race_name = CharField(max_length=100)
+                position = SerializerMethodField()
+        """)
+        assert repr(serializer) == expected
+
+    def test_uniq_together_validation_uses_model_fields_with_source_field(self):
+        class TestSerializer(serializers.ModelSerializer):
+            pos = serializers.IntegerField(source='position')
+
+            class Meta:
+                model = NullUniquenessTogetherModel
+                fields = ['race_name', 'pos']
+
+        serializer = TestSerializer()
+        expected = dedent("""
+            TestSerializer():
+                race_name = CharField(max_length=100, required=True)
+                pos = IntegerField(source='position')
+                class Meta:
+                    validators = [<UniqueTogetherValidator(queryset=NullUniquenessTogetherModel.objects.all(), fields=('race_name', 'pos'))>]
+        """)
+        assert repr(serializer) == expected
+
 
 class UniqueConstraintModel(models.Model):
     race_name = models.CharField(max_length=100)