Как сохранить родительскую и дочернюю таблицу вместе с JSON Arrary Django Restframework - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь сразу сохранить таблицы visit и visit_data с помощью django restframework.Я могу сделать это отдельно, когда я пытаюсь сохранить его сразу, я получил ошибку Метод .create() не поддерживает записи вложенных полей по умолчанию.Напишите явный метод .create() для сериализатора ssu.serializers.VisVisitsSerializer или установите read_only=True для вложенных полей сериализатора.

data

{

 "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"
        }
      ]

    },

  ]
}

serialize

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)

1 Ответ

0 голосов
/ 30 января 2019

Эта ошибка - точное описание того, что здесь происходит: метод сериализаторов .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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...