I have a serializer like this:
class ContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
fields = (
'account', 'first_name', 'last_name', 'email',
'phone_number',
)
validators = [
UniqueTogetherValidator(
queryset=Contact.objects.all(),
fields=['account', 'phone_number'],
message='A contact with this phone number is already exists.',
),
]
API returns the unique together validator errors as non_field_errors
. I want to show it in the specific field. In this case phone_number
.
How can I do that?
I made my own validator:
class UniqueForeignValidator(UniqueValidator):
message = 'The {field} must be unique within {foreign}'
requires_context = True
def __init__(self, queryset, foreign_field, message=None, lookup='exact'):
super().__init__(queryset, message, lookup)
self.foreign_field = foreign_field
def __call__(self, value, serializer_field):
foreign_pk = serializer_field.parent.initial_data[self.foreign_field]
self.message = self.message.format(field=serializer_field.field_name, foreign=self.foreign_field)
filter_kwargs = {f'{self.foreign_field}': foreign_pk}
self.queryset = self.queryset.filter(**filter_kwargs)
return super().__call__(value, serializer_field)
For your example, it should be called like this:
class ContactSerializer(serializers.ModelSerializer):
phone_number = fields.CharField(
validators=[
UniqueForeignValidator(
queryset=Contact.objects.all(),
foreign_field='account'
)
]
)
class Meta:
model = Contact
fields = (
'account', 'first_name', 'last_name', 'email',
'phone_number',
)
You can override the message when calling the validator in serializer
UniqueForeignValidator(
queryset=Contact.objects.all(),
foreign_field='account',
message='A contact with this phone number is already exists.'
)