Reputation: 3954
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
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