Отправить измененные данные в сериализатор в DRF API - PullRequest
0 голосов
/ 05 июня 2019

У меня есть API Django Rest Framework.

У меня есть такая модель:

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

Мой сериализатор выглядит так:

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

Мое представление вызывает две функции, valu_expression и expression_to_string, чтобы изменить данные, которые я отправляю в мой сериализатор:

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)

Не уверен, что я делаю неправильно, но у меня ошибка TypeError

__init__() got an unexpected keyword argument 'data'

и я явно не отправляю правильные данные в сериализатор.

1 Ответ

1 голос
/ 06 июня 2019

В вашем ExpressionSerializer, где вы унаследовали от ModelSerializer, вы не сохранили поведение ModelSerializer.__init__().

Вы должны добавить super(ExpressionSerializer, self).__init__(*args, **kwargs), как в следующем примере.

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

Это гарантирует, что во время инициализации вы используете метод ModelSerializer.__init__(). Аргументы функции *args, **kwargs предназначены для приема любых переменных, которые вы можете передать в эту функцию, и перенаправления их в метод super, чтобы вы могли использовать его так же, как обычный ModelSerializer, и расширять его своими собственные дополнительные аргументы и код.

...