Description
My team has run into a bug in UniqueTogetherValidator
where it does not work properly with fields with the source
attribute. If a field has a source
that is different than the field's name on the serializer, then that field is effectively ignored when checking for uniqueness violations, and the ValidationError
is not raised.
I am using a serializer set up like this. Note that UniqueTogetherValidator
is expecting the serializer's name for the fields
argument— you'll get an error on this line if you try to provide the source
name instead.
class ExampleSerializer(serializers.Serializer):
list_id = serializers.PrimaryKeyRelatedField(source='list')
position = serializers.IntegerField(source='ordering_key')
class Meta:
validators = [
UniqueTogetherValidator(
queryset=ToDoItem.objects.all(),
fields=['list_id', 'position']
)
]
I believe the bug occurs at this position in the code:
django-rest-framework/rest_framework/validators.py
Lines 167 to 178 in e13688f
On line 172, we check if field
(which comes from source
) is in self.fields
(which is the name on the serializer). If we're looking at the serializer above, then attrs.keys()
would be ['list', 'ordering_key']
and self.fields
is ['list_id', 'position']
.
This means that checked_values
will always be empty, and a ValidationError
will never be raised.
Checklist
- Raised initially as discussion #...
- This is not a feature request suitable for implementation outside this project. Please elaborate what it is:
- compatibility fix for new Django/Python version ...
- other type of bug fix
- other type of improvement that does not touch existing code or change existing behavior (e.g. wrapper for new Django field)
- I have reduced the issue to the simplest possible case.
REST Framework version: 3.15.1