python – Django rest_framework 3.22多个更新创建对象而不是更
发布时间:2020-12-20 13:06:49 所属栏目:Python 来源:网络整理
导读:我有一个API,需要将QuestionQueue及其相关的Question对象作为列表返回.我得到它很好地工作,它返回我想要的数据: class QuestionQueueSerializer(serializers.ModelSerializer): questions = QuestionSerializer( many=True,source='question_set',required=
我有一个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的更新方法,我在QuestionSerializer上设置为list_serializer_class: def update(self,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.他们在途中被剥离了.我不知道如何让这个工作. 解决方法
问题是在DRF的ModelSerializer中id字段是read_only = True因此它们在验证周期中被删除.使更新工作需要更多的工作.我不得不为
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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |