将修改后的数据发送到 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 数据输出到文件中 )