gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 12:06:02 25 4
gpt4 key购买 nike

我有一个 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, 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

问题是当调用我的 QuestionListSerializerupdate 方法时,validated_data 不包含问题的 ID。它们看起来都像是新创建的。 request.data 中的问题都有 ID。他们在途中的某个地方被剥夺了。我不知道如何让它发挥作用。

最佳答案

问题是 id 字段在 DRF 的 ModelSerializer 中是 read_only=True,因此它们在验证周期中被丢弃。使更新工作需要更多的工作。我必须为 DRF-bulk 做类似的事情我最终得到的解决方案是创建一个序列化程序混合,它将把 id 放回去。可以看源码here .我在 README 中还有一些其他信息.

如果代码被移动或类似的情况,这里是序列化器混合的复制粘贴:

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

关于python - Django rest_framework 3.22 多次更新创建对象而不是更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32055734/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com