I am working on a Django project. I have defined custom User model using AbstractBaseModel class. Below is my model representation for clarity.
# models.py
class User(AbstractBaseUser):
    id = models.AutoField(primary_key=True)
    firstname = models.CharField(max_length=50)
    lastname = models.CharField(max_length=50)
    email = models.EmailField(unique=True)
    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)
    is_staff = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['firstname', 'lastname']
    objects = UserManager()
    def save(self, *args, **kwargs):
        if not self.firstname or not self.lastname or not self.email or not self.password:
            raise ValueError('All required fields must be provided')
        super().save(*args, **kwargs)
    def __str__(self):
        return str(self.id) + '. ' + self.firstname + ' ' + self.lastname + ' (' + self.email + ')'
    def has_perm(self, perm, obj=None):
        return self.is_admin
    def has_module_perms(self, app_label):
        return True
    
    class Meta:
        db_table = 'users'
        verbose_name = 'User'
        verbose_name_plural = 'Users'
Below is my serializer class that serves purpose for User object validation upon its creation.
# serializers.py
from rest_framework import serializers
from .models import *
from django.contrib.auth.hashers import make_password, check_password
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['firstname', 'lastname', 'email', 'password']
    def create(self, validated_data):
        user = User.objects.create_user(
            email = validated_data['email'],
            firstname = validated_data['firstname'],
            lastname = validated_data['lastname'],
            password = make_password(validated_data['password'])
        )
        return user
Also, refer to my view that creates a user object for clarity.
# views.py
from .models import *
from .serializers import *
from rest_framework.response import Response
from rest_framework.views import APIView
class UserSignup(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors, status=400)
        serializer.save()
        return Response(serializer.data, status=201)
Here, as you may noted, my email field is unique and upon creating a user with duplicate email, my serializer gives below validated response.
{
    "email": [
        "User with this email already exists."
    ]
}
My problem statement is that I wish to have a custom response from serializer’s validation. There’s a way to add a validate method in the serializer class to add my custom validation, but here the problem would be to add validation for all my fields if I were to just add custom validation for email field.
What’s the right way to only change custom output for serializer error message that triggers for duplicate email field?
For e.g., I may want below output for duplicate email insertion.
{
    "email": [
        "Email already exists."
    ]
}
How do I achieve above?