Davtho1983
Davtho1983

Reputation: 3954

Send modified data to serializer in DRF API

I have a Django Rest Framework API.

I have a model like so:

class Expression(models.Model):
    expression = models.TextField()
    result = models.IntegerField()

My serializer is like so:

class ExpressionSerializer(serializers.ModelSerializer):

    def __init__(self):
        self.operator_mapping = {
            "add": " + ",
            "minus": " - ",
            "divide": " / ",
            "multiply": " * "
        }
        self.data = None

    class Meta:
        model = Expression
        fields = "__all__"

    def create(self, validated_data):
        expression = self.context.get('expression', None)
        result = self.context.get('result', None)

        expression_obj = Expression.objects.create(expression=expression, result=result)

        return expression_obj

My view calls two function, evaluate_expression and expression_to_string, to modify the data I send to my serializer:

class ExpressionAPIView(APIView):

    queryset = Expression.objects.all()
    serializer_class = ExpressionSerializer

    def __init__(self):
        self.operator_mapping = {
            "add": " + ",
            "minus": " - ",
            "divide": " / ",
            "multiply": " * "
        }


    def get(self, request):
        return Response({'data': request.data})

    def post(self, request):
        root = etree.XML(request.data['expression'])

        result = self.evaluate_expression(root)[0]

        exp_parsed = self.expression_to_string(root) + f" = {result}"

        serializer_data = request.data.get('expression', {})

        serializer_context  = {
            'expression': result,
            'result': exp_parsed
        }

        serializer = self.serializer_class(
            data=serializer_data,
            context=serializer_context
        )

        serializer.is_valid(raise_exception=True)
        serializer.save()

        return Response(serializer.validated_data, status=status.HTTP_201_CREATED)

Not sure what I'm doing wrong, but I have a TypeError

__init__() got an unexpected keyword argument 'data'

and I'm clearly not sending the right data to the serializer.

Upvotes: 0

Views: 223

Answers (1)

A. J. Parr
A. J. Parr

Reputation: 8026

In your ExpressionSerializer where you have inherited from ModelSerializer you have not preserved the ModelSerializer.__init__() behaviour.

You should add super(ExpressionSerializer, self).__init__(*args, **kwargs) like in the following example.

class ExpressionSerializer(serializers.ModelSerializer):

    def __init__(self, *args, **kwargs):
        self.operator_mapping = {
            "add": " + ",
            "minus": " - ",
            "divide": " / ",
            "multiply": " * "
        }
        super(ExpressionSerializer, self).__init__(*args, **kwargs)

    class Meta:
        model = Expression
        fields = "__all__"

    def create(self, validated_data):
        expression = self.context.get('expression', None)
        result = self.context.get('result', None)

        expression_obj = Expression.objects.create(expression=expression, result=result)

        return expression_obj

This ensure that during the initialization you are running the ModelSerializer.__init__() method. The *args, **kwargs function arguments are there to accept any variables that you might pass into that function and forward them to the super method, so you can use it just like a regular ModelSerializer and extend it with your own additional arguments and code.

Upvotes: 1

Related Questions