Django Rest:没有用M2M mod将正确的数据发送到序列化程序

2024-04-23 17:26:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个简单的关系结构,项目包含多个序列和一个中间元模型。你知道吗

我可以很容易地执行GET请求,并且它可以正确地格式化数据。但是,当我要发布已验证的数据变量时,该变量不包含格式正确的数据,因此我无法编写create/update方法。你知道吗

数据应该如下所示:

{'name': 'something', 
'seqrecords': [{
                'id': 5, 
                'sequence': 'ACGG...AAAA', 
                'name': 'Z78529',
                'order': 1
               },
               {
                'id': 6,
                'sequence': 'CGTA...ACCC',
                'name': 'Z78527',
                'order': 2
               }, 
}

但它看起来是这样的:

{'name': 'something',
 'projectmeta_set': [
                     OrderedDict([('order', 1)]),
                     OrderedDict([('order', 2)]),
                     OrderedDict([('order', 3)])
                    ]
}

序列化程序:

class ProjectMetaSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.ReadOnlyField(source='sequence.id')
    name = serializers.ReadOnlyField(source='sequence.name')

    class Meta:
        model = ProjectMeta
        fields = ['id', 'name', 'order']


class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    seqrecords = ProjectMetaSerializer(source='projectmeta_set', many=True)

    class Meta:
        model = Project
        fields = ['id', 'name', 'seqrecords']
        ReadOnlyField = ['id']

    def create(self, validated_data):
        project = Project(name=validated_data['name'])
        project.save()
        # This is where it all fails
        for seq in validated_data['seqrecords']:
            sequence = SeqRecord.objects.filter(id=seq['id'])
            meta = ProjectMeta(project=project,
                               sequence=sequence,
                               order=seq['order'])
            meta.save()
        return project

class SeqRecordSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = SeqRecord
        fields = ['id', 'name', 'sequence']
        read_only_fields = ['id']

型号:

class SeqRecord(models.Model):
    name = models.CharField(max_length=50)
    sequence = models.TextField()


class Project(models.Model):
    name = models.CharField(max_length=50)
    sequences = models.ManyToManyField(SeqRecord,
                                       through='primer_suggestion.ProjectMeta')


class ProjectMeta(models.Model):
    project = models.ForeignKey(Project)
    sequence = models.ForeignKey(SeqRecord)
    order = models.PositiveIntegerField()

查看

class ProjectApiList(viewsets.ViewSetMixin, generics.ListCreateAPIView):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer

是否有某种方法可以更改数据的验证,以便它返回我需要的东西,或者我可以以其他方式编写create和create函数?你知道吗


Tags: 数据nameprojectidfieldsmodelscreateorder
2条回答

要返回正确的数据格式,可以在ProjectSerializer中重写函数“To\ u internal”,如下所示:

class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    seqrecords = ProjectMetaSerializer(source='projectmeta_set', many=True)

    class Meta:
        model = Project
        fields = ['id', 'name', 'seqrecords']
        ReadOnlyField = ['id']

    def to_internal_value(self, data):
        ''' Override standard method so validated data have seqrecords '''
        context = super(ProjectSerializer, self).to_internal_value(data)
        context['seqrecords'] = data['seqrecords']

        return context

    def validate(self, data):
        ...

    def create(self, validated_data):
        ...
        return project

当然,此方法依赖于validate()中“seqrecords”字段的验证函数。你知道吗

正如您在ProjectMetaSerializer中看到的,字段idname是只读字段。所以不能在post请求中使用它们。你知道吗

class ProjectMetaSerializer(serializers.ModelSerializer):
    seqrecords = SeqRecordSerializer(many=True)

    class Meta:
        model = ProjectMeta
        fields = ['seqrecords',]


class ProjectSerializer(serializers.ModelSerializer):
    project_meta = ProjectMetaSerializer(many=True)

    class Meta:
        model = Project
        fields = ['id', 'name', 'project_meta']
        ReadOnlyField = ['id']

def create(self, validated_data):
    project = Project(name=validated_data['name'])
    project.save()
    # This is where it all fails
    for seq in validated_data['seqrecords']:
        sequence = SeqRecord.objects.filter(id=seq['id'])
        meta = ProjectMeta(project=project,
                           sequence=sequence,
                           order=seq['order'])
        meta.save()
    return project

class SeqRecordSerializer(serializers.ModelSerializer):
    class Meta:
        model = SeqRecord
        fields = ['id', 'name', 'sequence']

相关问题 更多 >