首页 > 解决方案 > 克隆多个对象并将它们返回以响应 DRF

问题描述

我的目标是克隆多个对象并将它们序列化,以便我可以在我的 REST Api 中返回结果。目前我的代码如下所示:

objects_to_clone = MyModel.objects.filter(...)
new_objects = []
for obj in objects_to_clone:
    clone = copy.deepcopy(file)
    clone.id = None
    # Do something else with the cloned object
    new_objects.append(clone)
serializer = MySerializer(data=new_objects, many=True) # YIELDS ERROR
if serializer.is_valid(raise_exception=True):
    serializer.save()
    return Response(serializer.data)

这段代码的问题是 Django 公正地产生

nonFieldErrors - 无效数据。需要一本字典,但得到了 MyModel

如何在不必寻找肮脏的解决方法的情况下克服这个问题?

标签: django-rest-framework

解决方案


您收到该错误是因为您将模型传递给序列化程序而不是字典。.values()您可以通过使用并指定要返回的字段将模型转换为字典。

values() 方法返回一个 QuerySet,它在用作可迭代对象时返回字典而不是模型实例。

例如,您当前拥有的评估结果是这样的

MyModel.objects.filter(...)
<QuerySet [<MyModel: Random Title>]>

但如果你使用values,相同查询的结果将是

MyModel.objects.filter(...).values()
<QuerySet [{'id': 1, 'name': 'Model 1'}, {'id': 2, 'name': 'Model 2'}]>

归根结底,您的代码将是这样的

objects_to_clone = MyModel.objects.filter(...).values()
new_objects = []
for obj in objects_to_clone:
    obj.id = None
    # Do something else with the cloned object
    new_objects.append(obj)
serializer = MySerializer(data=new_objects, many=True) # YIELDS ERROR
if serializer.is_valid(raise_exception=True):
    serializer.save()
return Response(serializer.data)

如果您不想将对象的 id 设置为 None 怎么办?该.values方法允许您指定所需模型的字段

所以更直接的代码修改版本将是

objects_to_clone = MyModel.objects.filter(...).values('name', 'description') # fake info of course
serializer = MySerializer(data=objects_to_clone, many=True) # YIELDS ERROR
if serializer.is_valid(raise_exception=True):
    serializer.save()
return Response(serializer.data)

推荐阅读