我有一个API需要将QuestionQueue及其相关的Question对象作为列表返回。我得到了很好的工作,它返回我想要的数据:
class QuestionQueueSerializer(serializers.ModelSerializer):
questions = QuestionSerializer(
many=True,
source='question_set',
required=False,
)
我无法获得有关此API的更新。我正在跟踪documentation多次写入。我有自己的名为ListSerializer
的自定义QuestionListSerializer
实例。这是我在QuestionQueueSerializer
中使用它的方式:
def update(self, instance, validated_data):
questions_data = validated_data.pop('question_set')
super(QuestionQueueSerializer, self).update(instance, validated_data)
question_list_serializer = QuestionSerializer(
instance=instance.question_set.all(),
data=questions_data,
many=True
)
if question_list_serializer.is_valid():
question_list_serializer.save(
company_id=instance.company_id,
question_queue_id=instance.id
)
return instance
这是QuestionListSerializer
上的更新方法,我在list_serializer_class
上设置为QuestionSerializer
:
def update(self, instance, validated_data):
questions_by_id = {_question.id: _question for _question in instance}
# Perform creations and updates.
ret = []
for question_data in validated_data:
question = None
if 'id' in question_data:
question = questions_by_id.get(question_data['id'], None)
if not question:
ret.append(self.child.create(question_data))
else:
ret.append(self.child.update(question, question_data))
question_ids_to_delete = set(questions_by_id.keys()) - {_q.id for _q in ret}
Question.objects.filter(id__in=question_ids_to_delete).update(delete_ts=timezone.now())
return ret
问题在于,当我的QuestionListSerializer
update
方法被调用时,validated_data
不包含问题的ID。他们看起来都像是新创造的。 request.data
中的问题都有ID。他们在途中被剥离了。我不知道如何让它发挥作用。
答案 0 :(得分:0)
问题是,id
字段在DRF的read_only=True
中为ModelSerializer
,因此它们会在验证周期中被删除。使更新工作需要更多的工作。我必须为DRF-bulk做类似的事情,我最终得到的解决方案是创建一个序列化器mixin,它会把id放回去。您可以看到源代码here。另外,我在README中有一些其他信息。
如果代码被移动或类似的东西,这里是序列化器mixin的复制粘贴:
class BulkSerializerMixin(object):
def to_internal_value(self, data):
ret = super(BulkSerializerMixin, self).to_internal_value(data)
id_attr = getattr(self.Meta, 'update_lookup_field', 'id')
request_method = getattr(getattr(self.context.get('view'), 'request'), 'method', '')
# add update_lookup_field field back to validated data
# since super by default strips out read-only fields
# hence id will no longer be present in validated_data
if all((isinstance(self.root, BulkListSerializer),
id_attr,
request_method in ('PUT', 'PATCH'))):
id_field = self.fields[id_attr]
id_value = id_field.get_value(data)
ret[id_attr] = id_value
return ret
答案 1 :(得分:0)
我在IRC上与tomchristie交谈过。在我的序列化程序中添加一个显式的id字段并使其不是read_only解决了这个问题。