加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读