Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7k
Description
My team has run into a bug inUniqueTogetherValidator where it does not work properly with fields with thesource attribute. If a field has asource that is different than the field's name on the serializer, then that field is effectively ignored when checking for uniqueness violations, and theValidationError is not raised.
I am using a serializer set up like this. Note thatUniqueTogetherValidator is expecting the serializer's name for thefields argument— you'll get an erroron this line if you try to provide thesource name instead.
classExampleSerializer(serializers.Serializer):list_id=serializers.PrimaryKeyRelatedField(source='list')position=serializers.IntegerField(source='ordering_key')classMeta: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 ine13688f
| else: | |
| # Ignore validation if all field values are unchanged | |
| checked_values= [ | |
| value | |
| forfield,valueinattrs.items() | |
| iffieldinself.fieldsandvalue!=getattr(serializer.instance,field) | |
| ] | |
| ifchecked_valuesandNonenotinchecked_valuesandqs_exists(queryset): | |
| field_names=', '.join(self.fields) | |
| message=self.message.format(field_names=field_names) | |
| raiseValidationError(message,code='unique') |
Online 172, we check iffield (which comes fromsource) is inself.fields (which is the name on the serializer). If we're looking at the serializer above, thenattrs.keys() would be['list', 'ordering_key'] andself.fields is['list_id', 'position'].
This means thatchecked_values will always be empty, and aValidationError 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