Python Django rest_framework 3.22多次更新创建对象而不是更新

Python Django rest_framework 3.22多次更新创建对象而不是更新,python,django,rest,django-rest-framework,Python,Django,Rest,Django Rest Framework,我有一个API,它需要以列表的形式返回QuestionQueue及其关联的问题对象。我让它工作得很好,它以我想要的方式返回数据: class QuestionQueueSerializer(serializers.ModelSerializer): questions = QuestionSerializer( many=True, source='question_set', required=False, ) 我在获取此API

我有一个API,它需要以列表的形式返回QuestionQueue及其关联的问题对象。我让它工作得很好,它以我想要的方式返回数据:

class QuestionQueueSerializer(serializers.ModelSerializer):
    questions = QuestionSerializer(
        many=True,
        source='question_set',
        required=False,
    )
我在获取此API的更新时遇到问题。我正在遵循多次写入的规则。我有自己的自定义
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\u serializer\u类

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\u数据
不包含问题的ID。它们看起来都是新创建的。
request.data
中的问题都有ID。他们在路上的某个地方脱光了衣服。我不知道如何让它工作。

问题是,
id
字段在DRF的
ModelSerializer
中是
read\u=True
,因此它们在验证周期中被丢弃。使更新生效需要更多的工作。我不得不做一些类似的事情,最终得到的解决方案是创建一个序列化程序mixin,将id放回原处。您可以看到源代码。此外,我还有一些额外的信息在报告中

如果代码被移动或类似情况,下面是序列化程序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

我在IRC上和汤姆克里斯蒂谈过。在我的序列化程序中添加一个显式id字段并使其不可读只解决了这个问题。

我尝试将此代码复制到我的代码库中,但无法使其工作。我左顾右盼都没有用。在某些对内部值的调用中,`context`不包含
视图
。如果根目录是我的列表的一个实例,则它不包含
字段
。我准备完全放弃rest_框架,因为要让它做我需要的事情非常困难。如果root是一个列表,它将不包含任何字段<代码>根.child.field将存在<代码>列表序列化程序不包含任何字段。所有字段都回退到子序列化程序字段。