首页 > 解决方案 > 如何从 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)

标签: python-3.xdjango-rest-frameworkdjango-serializer

解决方案


您遇到的错误是这里发生的事情的确切描述:.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)

推荐阅读