将修改后的数据发送到 DRF API 中的序列化程序

Posted

技术标签:

【中文标题】将修改后的数据发送到 DRF API 中的序列化程序【英文标题】:Send modified data to serializer in DRF API 【发布时间】:2019-06-05 19:42:14 【问题描述】:

我有一个 Django Rest Framework API。

我有一个这样的模型:

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

我的视图调用了两个函数,evaluate_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'

而且我显然没有向序列化程序发送正确的数据。

【问题讨论】:

我没有看到 operator_mapping 变量的任何用法...我错过了什么吗? 嘿,是的,它用于两个未显示的功能 - 抱歉,这里是错误的 【参考方案1】:

在您从ModelSerializer 继承的ExpressionSerializer 中,您没有保留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 函数参数用于接受您可能传递给该函数的 任何 变量并将它们转发给超级方法,因此您可以像使用常规 ModelSerializer 一样使用它并扩展它您自己的附加参数和代码。

【讨论】:

这解决了一个问题,但我仍然无法将数据传递给序列化程序 在管理员中我得到错误没有这样的列:expressions_expression.result,在我的 api 前端我有 "non_field_errors": [ "Invalid data. Expected a dictionary, but got str." ] 你是在发送一个带有“表达式”键/值还是纯字符串的 json 对象? 还有 serializer_context = 'expression': exp_parsed, 'result': result - 我把它们弄错了 好吧,我想通了——我只需要执行 serializer_data = 'expression': exp_parsed, 'result': result 并且不需要提供上下文

以上是关于将修改后的数据发送到 DRF API 中的序列化程序的主要内容,如果未能解决你的问题,请参考以下文章

GroovyXml 反序列化 ( 使用 XmlParser 解析 Xml 文件 | 删除 Xml 文件中的节点 | 增加 Xml 文件中的节点 | 将修改后的 Xml 数据输出到文件中 )

DRF序列化

DRF序列化

DRF学习

drf中的Serialiazer序列化器

DRF框架