1

So I want to create a custom message for the different fail based on the serializer validation. But I was only able to find how to create a standard custom response for success and fail only. Though the only response I want to create is for the failed prompt message.

I found one of the posts but it's not really what I wanted for the error code source: Django Rest Framework custom response message

Basically, the error message must be based on the specific validation error in serializer.py

Here is my code

serializer.py

class UserCreate2Serializer(ModelSerializer):
email = EmailField(label='Email Address')
valid_time_formats = ['%H:%M', '%I:%M%p', '%I:%M %p']
birthTime = serializers.TimeField(format='%I:%M %p', input_formats=valid_time_formats, allow_null=True, required=False)

class Meta:
    model = MyUser
    fields = ['username', 'password', 'email', 'first_name', 'last_name', 'gender', 'nric', 'birthday', 'birthTime', 'ethnicGroup']
    extra_kwargs = {"password": {"write_only": True}}

def validate(self, data):  # to validate if the user have been used
    email = data['email']
    user_queryset = MyUser.objects.filter(email=email)
    if user_queryset.exists():
        raise ValidationError("This user has already registered.")
    return data

# Custom create function
def create(self, validated_data):
    username = validated_data['username']
    password = validated_data['password']
    email = validated_data['email']
    first_name = validated_data['first_name']
    last_name = validated_data['last_name']
    gender = validated_data['gender']
    nric = validated_data['nric']
    birthday = validated_data['birthday']
    birthTime = validated_data['birthTime']
    ethnicGroup = validated_data['ethnicGroup']

    user_obj = MyUser(
        username = username,
        email = email,
        first_name = first_name,
        last_name = last_name,
        gender = gender,
        nric = nric,
        birthday = birthday,
        birthTime = birthTime,
        ethnicGroup = ethnicGroup,
    )
    user_obj.set_password(password)
    user_obj.save()
    return validated_data

views.py

class CreateUser2View(CreateAPIView):
    permission_classes = [AllowAny]
    serializer_class = UserCreate2Serializer
    queryset = MyUser.objects.all()

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if not serializer.is_valid(raise_exception=False):
            return Response({"promptmsg": "You have failed to register an account"}, status=status.HTTP_400_BAD_REQUEST)

        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response({'promptmsg': 'You have successfully register'}, status=status.HTTP_201_CREATED, headers=headers)

As you can see from serializer validate section, if email exists, it will give an error message of this user has been registered. Same for username but Django has its own validation for it since it is built in.

Is there a way for the error message to be like this: if username is taken, instead of this

    "username": [
    "A user with that username already exists."
]

to this

    "promptmsg": [
    "A user with that username already exists."
] 

--updated--

models.py

class MyUser(AbstractUser):
    userId = models.AutoField(primary_key=True)
    gender = models.CharField(max_length=6, blank=True, null=True)
    nric = models.CharField(max_length=9, blank=True, null=True)
    birthday = models.DateField(blank=True, null=True)
    birthTime = models.TimeField(blank=True, null=True)
    ethnicGroup = models.CharField(max_length=30, blank=True, null=True)

    def __str__(self):
    return self.username
Mika Sundland
  • 18,120
  • 16
  • 38
  • 50
Jin Nii Sama
  • 707
  • 1
  • 16
  • 33
  • As far as I see,The error log with `"username": [ "A user with that username already exists." ]` will never show up.The `{"promptmsg": "You have failed to register an account"}` is current return? – Ykh Dec 27 '17 at 02:58
  • Because of this code `if not serializer.is_valid(raise_exception=False): return Response({"promptmsg": "You have failed to register an account"}, status=status.HTTP_400_BAD_REQUEST)` Therefore if the create is not valid, it will only display promptmsg": "You have failed to register an account – Jin Nii Sama Dec 27 '17 at 03:00
  • You want you error response like `{promptmsg:xxx}`? I must remind you,if you do like this,you will never know which field in model cause the error! – Ykh Dec 27 '17 at 03:04
  • if i remove that code, it will show `"username": [ "A user with that username already exists." ]` However i wanted it to be `"promptmsg": [ "A user with that username already exists." ]` – Jin Nii Sama Dec 27 '17 at 03:05
  • Yes i understand. But my partner says he wanted it that way . – Jin Nii Sama Dec 27 '17 at 03:08
  • Just username to promptmsg? How do you handle `"username": [ "A user with that username already exists." ], "password": ["This field is required."]` – Ykh Dec 27 '17 at 03:08
  • Just username to promptmsg? How do you handle `"username": [ "A user with that username already exists." ], "password": ["This field is required."]` – Ykh Dec 27 '17 at 03:09
  • 1
    does this help? https://stackoverflow.com/questions/28197199/how-to-change-validation-error-responses-in-drf – Thomas Jiang Dec 27 '17 at 03:12
  • apparently, django validate from top to bottom, so if the top part(for eg:username) has validation error, it will stop the process and just sent you the error message. Furthermore , the error message is inconsistant. For the email validation, the error message is this `"non_field_errors": [ "This user has already registered." ]` I wanted it to be like this `"email": [ "This user has already registered." ]` – Jin Nii Sama Dec 27 '17 at 03:14
  • If you want handle all error msg not based on DRF,this is help.If you want keep DRF error just change format,this's not.Answer the question i ask you before,how do you handle `"username": [ "A user with that username already exists." ], "password": ["This field is required."] `,to `"promptmsg": [ "A user with that username already exists." ], "password": ["This field is required."] `? – Ykh Dec 27 '17 at 03:15
  • i think django is the one who handle these username and password field. Since i am using their auto create user table except i add in extra field – Jin Nii Sama Dec 27 '17 at 03:17
  • If you don't answer the question i asked before,I really don't know which format is you want?Just is username change to promptmsg?Or format all error msg to one string named with promptmsg in json? – Ykh Dec 27 '17 at 03:20
  • 1
    If you want `"email": [ "This user has already registered." ]`, write like `raise ValidationError({"email":"This user has already registered."})` – Ykh Dec 27 '17 at 03:22
  • Sorry, it seems i misunderstood your question. But yes that is what i want. Thank you. Sorry for the trouble – Jin Nii Sama Dec 27 '17 at 03:26
  • So that mean what??Just is username change to promptmsg?Or format all error msg to one string named with promptmsg in json? – Ykh Dec 27 '17 at 03:35
  • because my old validation for email gave this `"non_field_errors": [ "This user has already registered." ]` which is inconsistant to the username and password validation so i wanted it to be promptmsg : -----. But ur answer has change the non_field_errors to email so it is ok to use back to the original validation – Jin Nii Sama Dec 27 '17 at 03:58

1 Answers1

0

You can get this list of errors at serializer.errors look how validation works

Hugo Brilhante
  • 596
  • 4
  • 13