python-3.x - 如何从 json arrary Django Restframework 一起保存父表和子表
问题描述
我正在尝试使用 django restframework 一次保存访问和访问数据表。当我尝试一次保存时,我可以单独执行此操作我收到错误默认情况下该.create()
方法不支持可写嵌套字段。.create()
为 serializer编写显式方法ssu.serializers.VisVisitsSerializer
,或read_only=True
在嵌套的序列化器字段上设置。
数据
{
"user" : "1",
"visits": [
{
"action": "i",
"local_id": "170",
"visit_id": "",
"school_program_id": "1",
"data": [
{
"Active": "1",
"LocalID": "1904",
"VisitDataID": "",
"VisitGroupNo": "",
"VisitID": "170",
"VisitParamID": "342",
"VisitParamValID": "",
"VisitParamValue": "41"
},
{
"Active": "1",
"LocalID": "1905",
"VisitDataID": "",
"VisitGroupNo": "",
"VisitID": "170",
"VisitParamID": "313",
"VisitParamValID": "",
"VisitParamValue": "29"
}
]
},
{
"action": "i",
"local_id": "172",
"visit_id": "",
"school_program_id": "1",
"data": [
{
"Active": "1",
"LocalID": "190",
"VisitDataID": "",
"VisitGroupNo": "",
"VisitID": "10",
"VisitParamID": "342",
"VisitParamValID": "",
"VisitParamValue": "41"
},
{
"Active": "1",
"LocalID": "1902",
"VisitDataID": "",
"VisitGroupNo": "",
"VisitID": "170",
"VisitParamID": "313",
"VisitParamValID": "",
"VisitParamValue": "29"
}
]
},
{
"action": "i",
"local_id": "172",
"visit_id": "",
"school_program_id": "1",
"data": [
{
"Active": "1",
"LocalID": "1904",
"VisitDataID": "",
"VisitGroupNo": "",
"VisitID": "170",
"VisitParamID": "342",
"VisitParamValID": "",
"VisitParamValue": "41"
},
{
"Active": "1",
"LocalID": "1906",
"VisitDataID": "",
"VisitGroupNo": "",
"VisitID": "170",
"VisitParamID": "313",
"VisitParamValID": "",
"VisitParamValue": "29"
}
]
},
]
}
连载
class VisVisitDataSerializer(serializers.ModelSerializer):
local_id = serializers.IntegerField(source='app_local_id',read_only=True)
data_id = serializers.IntegerField(source='vdata_id',read_only=True)
parameter_id = serializers.IntegerField(source='vparameter_id',required=False)
value_id = serializers.IntegerField(source='vpvalue_id',required=False)
value_text = serializers.CharField(source='vpvalue_text',required=False)
class Meta:
model = VisVisitData
fields = ('local_id',
'data_id',
'parameter_id',
'value_id',
'group_no',
'value_text')
class VisVisitsSerializer(serializers.ModelSerializer):
data = VisVisitDataSerializer(many=True)
local_id = serializers.IntegerField(source='app_local_id')
local_created_at = serializers.DateTimeField(source='app_local_creation_timestamp')
local_modified_at = serializers.DateTimeField(source='app_local_modified_timestamp')
visit_no = serializers.IntegerField(source='visit_day')
school_id = serializers.CharField(source='school_program.school.school_id',read_only=True)
visit_date = serializers.DateField(source='date_of_visit',format="%Y-%m-%d", input_formats=['%d-%m-%Y', 'iso-8601'])
active = serializers.IntegerField(source='is_valid')
visit_type = serializers.IntegerField(source='type_of_data')
class Meta:
model = VisVisits
fields = ('local_id','visit_id','visit_no',
'school_program','school_id','program_id',
'visit_date','geo_location','applicable_class',
'total_attendance','active','local_created_at',
'local_modified_at','visit_type','user','data')
read_only_fields = ['visit_id']
def create(self, validated_data):
visits_data = validated_data.pop('data')
visit = VisVisits.objects.create(**validated_data)
for visit_data in visits_data:
VisVisitData.objects.create(visit=visit, **visit_data)
return visit
看法
@api_view(['POST'])
def SaveVisitView(request):
if request.method == 'POST':
for i in range(len(visits['visits']))
serializer = VisVisitsSerializer(data=visits['visits'][i])
if serializer.is_valid():
serializer.save()
else:
visits_issues.append({'local_id':visits['visits'][i]['local_id'],
'validation_issues': serializer.errors})
return Response(visits_issues, status=status.HTTP_201_CREATED)
解决方案
您遇到的错误是这里发生的事情的确切描述:.create()
默认情况下,序列化程序的方法不支持嵌套写入。
因此,您必须重写序列化程序创建的方法VisVisitsSerializer
,如下所示:
class VisVisitsSerializer(serializers.ModelSerializer):
<fields_and_meta>
def create(self, validated_data):
if 'data' in validated_data:
data = validated_data.pop('data')
<call the VisVisitDataSerializer creation method here>
return super().create(validated_data)
推荐阅读
- image-processing - Gstreamer 模拟视频采集
- sql - PostgreSQL 两个表与表达式关系
- jpa - Spring数据jpa id使unsigne?
- c# - C# 获取特殊字符前的空白位置
- typescript - 如何从流中创建打字稿对象
- javascript - 在 html5-qrcode.min.js 上选择后置摄像头
- jenkins - 如何使用 Jenkins 中的凭据克隆 bitbucket 源代码存储库
- c# - WPF 无法使密码框元素的角变圆
- javascript - js中的这个排序功能是如何工作的?
- php - 对使用 memcache 感到困惑并比较哪种解决方案更好