Python 验证的数据字段不同于数据字段Django Rest嵌套序列化程序
因此,我在django中使用序列化程序,并希望在响应中更改字段的名称,当我意识到我所做的更改没有被计算在内时,我进行了一些挖掘,发现我的已验证的_数据与我的数据不同 我在这里的目标是为序列化程序提供一个python对象,该序列化程序具有不同于我要返回的名称的字段,因此我在字段中使用了'source='参数 请注意,更改python对象字段的名称不是一个选项 下面是python对象:Python 验证的数据字段不同于数据字段Django Rest嵌套序列化程序,python,json,django,django-rest-framework,django-serializer,Python,Json,Django,Django Rest Framework,Django Serializer,因此,我在django中使用序列化程序,并希望在响应中更改字段的名称,当我意识到我所做的更改没有被计算在内时,我进行了一些挖掘,发现我的已验证的_数据与我的数据不同 我在这里的目标是为序列化程序提供一个python对象,该序列化程序具有不同于我要返回的名称的字段,因此我在字段中使用了'source='参数 请注意,更改python对象字段的名称不是一个选项 下面是python对象: class Flow(object): """Just a regular python object""
class Flow(object):
"""Just a regular python object"""
def __init__(self, name=None, flow_uid=None, data_type=None, parent=None, container=None):
"""This has more fields than the serializer is waiting"""
self._parent = None
self._container = None
self.name = name
self.data_type = data_type
self.flow_uid = flow_uid
以及以下序列化程序(我使用的是嵌套表示)序列化程序.py
from rest_framework.fields import CharField, IntegerField, ListField, JSONField
from rest_framework.serializers import Serializer
class OutputSerializer(Serializer):
uid = CharField(max_length=36)
name = CharField(max_length=100)
description = CharField(max_length=100)
class FlowSerializer(Serializer):
uid = CharField(source='flow_uid', max_length=36) # I want 'uid' in my response not 'flow_uid'
name = CharField(max_length=100)
data_type = CharField(max_length=100)
class Meta:
fields = '___all___'
def to_representation(self, instance):
instance = super(FlowSerializer, self).to_representation(instance)
#Here instance = OrderedDict([('uid', 'uid_value'), ('name', 'name_value'), ('data_type', 'data_value')])
return instance
class FlowOutputSerializer(OutputSerializer):
columns = FlowSerializer(many=True)
class AddTransformationViewSet(ViewSet):
"""Handle available "actions" for BrickModel operations"""
def list(self, request, parent_lookup_analyses: str):
"""The method I call for this test"""
flow1 = Flow(name="name1", flow_uid='flow_uid_value1', data_type='str')
flow2 = Flow(name="name2", flow_uid='flow_uid_value2', data_type='str')
flow1_ser = FlowSerializer(flow1)
flow2_ser = FlowSerializer(flow2)
dummy_col = {
"name": "output_name",
"description": "output_description",
"uid": "output_uid",
"columns":
[
flow2_ser.data, # Debug: {'uid': 'flow_uid_value2', 'name': 'name2', 'data_type': 'str'}
flow1_ser.data # Debug: {'uid': 'flow_uid_value1', 'name': 'name1', 'data_type': 'str'}
]
}
#Debug dummy_col: {'name': 'output_name', 'description': 'output_description', 'uid': 'output_uid', 'columns': [{'uid': 'flow_uid_value2', 'name': 'name2', 'data_type': 'str'}, {'uid': 'flow_uid_value1', 'name': 'name1', 'data_type': 'str'}]}
dummy_serializer: FlowOutputSerializer = FlowOutputSerializer(data=dummy_col)
dummy_serializer.is_valid(raise_exception=True)
# Debug dummy_serializer.data: {'uid': 'output_uid', 'name': 'output_name', 'description': 'output_description', 'columns': [OrderedDict([('uid', 'flow_uid_value2'), ('name', 'name2'), ('data_type', 'str')]), OrderedDict([('uid', 'flow_uid_value1'), ('name', 'name1'), ('data_type', 'str')])]}
# Debug dummy_serializer.validated_data: OrderedDict([('uid', 'output_uid'), ('name', 'output_name'), ('description', 'output_description'), ('columns', [OrderedDict([('flow_uid', 'flow_uid_value2'), ('name', 'name2'), ('data_type', 'str')]), OrderedDict([('flow_uid', 'flow_uid_value1'), ('name', 'name1'), ('data_type', 'str')])])])
return Response(data=dummy_serializer.validated_data, status=status.HTTP_201_CREATED)
viewsets.py
from rest_framework.fields import CharField, IntegerField, ListField, JSONField
from rest_framework.serializers import Serializer
class OutputSerializer(Serializer):
uid = CharField(max_length=36)
name = CharField(max_length=100)
description = CharField(max_length=100)
class FlowSerializer(Serializer):
uid = CharField(source='flow_uid', max_length=36) # I want 'uid' in my response not 'flow_uid'
name = CharField(max_length=100)
data_type = CharField(max_length=100)
class Meta:
fields = '___all___'
def to_representation(self, instance):
instance = super(FlowSerializer, self).to_representation(instance)
#Here instance = OrderedDict([('uid', 'uid_value'), ('name', 'name_value'), ('data_type', 'data_value')])
return instance
class FlowOutputSerializer(OutputSerializer):
columns = FlowSerializer(many=True)
class AddTransformationViewSet(ViewSet):
"""Handle available "actions" for BrickModel operations"""
def list(self, request, parent_lookup_analyses: str):
"""The method I call for this test"""
flow1 = Flow(name="name1", flow_uid='flow_uid_value1', data_type='str')
flow2 = Flow(name="name2", flow_uid='flow_uid_value2', data_type='str')
flow1_ser = FlowSerializer(flow1)
flow2_ser = FlowSerializer(flow2)
dummy_col = {
"name": "output_name",
"description": "output_description",
"uid": "output_uid",
"columns":
[
flow2_ser.data, # Debug: {'uid': 'flow_uid_value2', 'name': 'name2', 'data_type': 'str'}
flow1_ser.data # Debug: {'uid': 'flow_uid_value1', 'name': 'name1', 'data_type': 'str'}
]
}
#Debug dummy_col: {'name': 'output_name', 'description': 'output_description', 'uid': 'output_uid', 'columns': [{'uid': 'flow_uid_value2', 'name': 'name2', 'data_type': 'str'}, {'uid': 'flow_uid_value1', 'name': 'name1', 'data_type': 'str'}]}
dummy_serializer: FlowOutputSerializer = FlowOutputSerializer(data=dummy_col)
dummy_serializer.is_valid(raise_exception=True)
# Debug dummy_serializer.data: {'uid': 'output_uid', 'name': 'output_name', 'description': 'output_description', 'columns': [OrderedDict([('uid', 'flow_uid_value2'), ('name', 'name2'), ('data_type', 'str')]), OrderedDict([('uid', 'flow_uid_value1'), ('name', 'name1'), ('data_type', 'str')])]}
# Debug dummy_serializer.validated_data: OrderedDict([('uid', 'output_uid'), ('name', 'output_name'), ('description', 'output_description'), ('columns', [OrderedDict([('flow_uid', 'flow_uid_value2'), ('name', 'name2'), ('data_type', 'str')]), OrderedDict([('flow_uid', 'flow_uid_value1'), ('name', 'name1'), ('data_type', 'str')])])])
return Response(data=dummy_serializer.validated_data, status=status.HTTP_201_CREATED)
预期反应:
{
...
"columns": [
{
"uid": "flow_uid_value2",
"name": "name2",
"data_type": "str"
},
{
"uid": "flow_uid_value1",
"name": "name1",
"data_type": "str"
}
]
}
我得到的(我希望“flow\u uid”是“uid”):
在这种情况下使用.data而不是.validated\u数据是否有任何特别的危险?
这种行为的原因是什么
在这种情况下使用.data而不是.validated\u数据是否有任何特别的危险?这种行为的原因是什么
serializer.validated_数据
用于Python对象。因此,由于自定义source
值,它将公开flow\u uid
serializer.data
将是调用save
后save()的序列化结果
因此,您应该始终在响应中使用serializer.data
,并在与模型或内部项目代码交互的任何代码中保留serializer.validated\u data
:
Response(data=dummy_serializer.data, status=status.HTTP_201_CREATED)
在这种情况下使用.data而不是.validated\u数据是否有任何特别的危险?这种行为的原因是什么
serializer.validated_数据
用于Python对象。因此,由于自定义source
值,它将公开flow\u uid
serializer.data
将是调用save
后save()的序列化结果
因此,您应该始终在响应中使用serializer.data
,并在与模型或内部项目代码交互的任何代码中保留serializer.validated\u data
:
Response(data=dummy_serializer.data, status=status.HTTP_201_CREATED)
在这种情况下,如果我希望在响应中使用“uid”而不是“flow\u uid”,同时保持python对象的结构完整,那么正确的方法是什么?谢谢您的帮助,但是我觉得这里仍然有问题,我仍然希望进行基本字段验证。例如,我尝试给我的Charfield
一个Integer
,它只是把它转换成str
,而不是告诉我出了什么问题。可能与以下内容有关:DRF char field code说:“我们允许将基本数字强制转换为字符串,但其他类型应该失败。例如,不清楚布尔值是否应该表示为true
或true
,列表等组合可能是用户错误。”在这种情况下,如果我希望在响应中使用“uid”而不是“flow\u uid”,同时保持python对象的结构完整,那么正确的方法是什么?谢谢您的帮助,但是我觉得这里仍然有问题,我仍然希望进行基本字段验证。例如,我尝试给我的Charfield
一个Integer
,它只是把它转换成str
,而不是告诉我出了什么问题。可能与以下内容有关:DRF char field code说:“我们允许将基本数字强制转换为字符串,但其他类型应该失败。例如,不清楚布尔值是否应该表示为true
或true
,列表等组合可能是用户错误。”