Home > other >  Django: How can I override unique validators error message?
Django: How can I override unique validators error message?

Time:09-23

I have a custom user model class

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager

class CustomUser(AbstractBaseUser, PermissionsMixin)
    ...
    email = models.EmailField(_('email address'), unique=True)
    user_name = models.CharField(max_length=150, unique=True) # Full name
    phone_number = models.CharField(max_length=20, unique=True)

And related view

class CustomUserViewSet(viewsets.ModelViewSet):
    pagination_class = BasePagination
    queryset = CustomUser.objects.all()
    ...

    def create(self, request, *args, **kwargs):
        serializer = CustomUserSerializer(data=request.data)

        if serializer.is_valid():
            user = serializer.save()
            if user:
                json = serializer.data
                send_invitation_email(
                    user=user,
                    email=json["email"],
                    password=request.data["password"],
                    phone=json["phone_number"]
                )
                create_chats(user)
                return Response(json, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

In case of email, username duplicate I have the following error message:

{"user_name":["custom user с таким user name уже существует."]}

How can I override error this message with my custom message:

{"user_name":["Пользоватль с таким именем уже существует."]}

UPDATE I updated my serializer

class CustomUserSerializer(serializers.ModelSerializer):
    avatar = serializers.FileField(use_url=False, required=False)
    organization = OrganizationSimpleSerializer(required=False, read_only=True)
    user_type = DepartmentSerializer(required=False, read_only=True)

    organization_id = serializers.IntegerField(required=True, write_only=True)
    user_type_id = serializers.IntegerField(required=True, write_only=True)

    class Meta:
        model = CustomUser
        fields = [
            ...
        ]
        read_only_fields = ("id",)
        extra_kwargs = {}
        extra_kwargs = {
            "password": {"write_only": True},
            "user_name": {
                "error_messages": {"unique": "Пользоватль с таким именем уже существует."}
            },
            "email": {
                "error_messages": {"unique": "Пользоватль с такой электронной почтой уже существует"}
            },
            "phone_number": {
                "error_messages": {"unique": "Пользоватль с таким телефоном уже существует"}
            }
        }

But I don't see my error message, I see this:

{"user_name":["Пользователь с таким user name уже существует."],"phone_number":["Пользователь с таким phone number уже существует."]}

It looks like check on the serializer level isn't working

CodePudding user response:

Here is the solution you can try.

from rest_framework.validators import UniqueValidator


class CustomUserSerializer(serializers.ModelSerializer):
    user_name = serializers.CharField(validators=[
        UniqueValidator(
            queryset=CustomUser.objects.all(),
            message="Пользоватль с таким именем уже существует."
        )
    ])

    user_name = serializers.EmailField(validators=[
        UniqueValidator(
            queryset=CustomUser.objects.all(),
            message="Your custom email unique message here. "
        )
    ])
    # and so on... for your other fields with unique=True

    class Meta:
        model = CustomUser  # your custom user model
        fields = '__all__'  # your fields here

Here is the rest-framework validators docs link. Or you can override the default errors messages in your model.py too:

class CustomUser(models.Model):
    user_name = models.CharField(max_length=128, unique=True, error_messages={
        "unique": "Пользоватль с таким именем уже существует."
    })
    email = models.EmailField(max_length=128, unique=True, error_messages={
        "unique": "Your custom error message"
    })

    #...

Here is the django doc link.

Note: Already proposed solutions that isn't working for unique=True validator but will work for overriding other validation messages.

You can override the default error messages in your serializers by giving some extra_kwargs or even by adding a custom error message in your serializer field.

# by using extra_kwargs

class CustomUserSerializer(serializers.ModelSerializer):
    # ...
    class Meta:
        model = CustomUser # your custom user model
        fields = '__all__' # your fields here
        extra_kwargs = {
            "user_name": {
                "error_messages": {"unique": "Пользоватль с таким именем уже существует."}
            },
            # you can do this same for your email field
            "email": {
                "error_messages": {"unique": "Your custom email unique message here. "}
            }
        }

Here is the adding custom message to the field explicitly.

class CustomUserSerializer(serializers.ModelSerializer):
    user_name = serializers.CharField(
        error_messages={"unique": "Пользоватль с таким именем уже существует."}
    )
    email = serializers.EmailField(
        error_messages={"unique": "Your custom email unique message here. "}
    )
    
   # ...

But I personally prefer to customize the error message using the first method by providing the extra_kwargs.

CodePudding user response:

you can add your message in your validator in serialzier like this

so in CustomUserSerializer put this code :

def validate_username(self,value):
   if your_logic:
      return value
   raise serializers.ValidationError('Пользоватль с таким именем уже существует.')
  • Related