我有一个简单的关系结构,项目包含几个带有中间元模型的序列。
我可以轻松地执行GET请求并正确格式化数据。但是,当我想发布validated_data变量时,不包含正确格式化的数据,所以我无法编写创建/更新方法。
数据应如下所示:
{'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
有没有办法改变数据的验证,所以它返回我需要的东西,或者我可以用其他方式编写创建和函数?
答案 0 :(得分:0)
正如您在ProjectMetaSerializer
中看到的,字段id
和name
是ReadOnlyFields。因此,您无法在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']
答案 1 :(得分:0)
要返回正确的数据格式,可以在ProjectSerializer中覆盖函数“to_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”字段的良好验证功能。