Ravexina
Ravexina

Reputation: 2848

Custom format for serializer ValidationError

Iv'e got a custom object-level validator in one of my serializers:

def validate(self, data):
    # some checks on token
    # set token to True or False
    
    if not token:
        raise serializers.ValidationError(
            {
                "status": "failed",
                "message": _("token is not valid"),
            }
        )
    
    return data

What I expect to get as an output is this:

{
    "status": "failed",
    "message": "token is not valid"
}

However, what I'm actually getting is:

{
    "status": [
        "failed"
    ],
    "message": [
        "token is not valid"
    ]
}

Is there anyway to achieve what I'm looking for?

Upvotes: 2

Views: 1540

Answers (2)

Kevin Dongmo F.
Kevin Dongmo F.

Reputation: 11

It will be easier for you to achieve this by validating your token at the view side instead. For example your view will look like this:

# Your view
class MyView(APIView):
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(
            data=request.data, context={"request": request}
        )
        serializer.is_valid()
        token = serializer.validated_data["token"]
        if not token:
            return Response(
                data={"status": "failed", "message": _("token is not valid")},
                status=401
            )
        # The rest of your code below

You can set the line serializer.is_valid() to serializer.is_valid(raise_exception=True) if you have other validations to do. I hope this will help

Upvotes: -1

Ravexina
Ravexina

Reputation: 2848

Create a custom ValidatorError class:

from rest_framework import serializers, status
from rest_framework.exceptions import APIException


class PlainValidationError(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_detail = _("Invalid input.")
    default_code = "invalid"

    def __init__(self, detail=None, code=None):
        if not isinstance(detail, dict):
            raise serializers.ValidationError("Invalid Input")
        self.detail = detail

Instead of using serializers.ValidationError use your custom ValidationError class:

def validate(self, data):
    # some checks on token
    # set token to True or False
    
    if not token:
        raise PlainValidationError(
            {
                "status": "failed",
                "message": _("token is not valid"),
            }
        )
    
    return data

It's not perfect but it does the job for me.

Upvotes: 3

Related Questions