克隆多个对象并将其返回以响应DRF

时间:2019-09-20 10:22:47

标签: django-rest-framework

我的目标是克隆多个对象并将其序列化,以便可以将结果返回到我的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

如何无需发现肮脏的解决方法来克服这一问题?

1 个答案:

答案 0 :(得分:1)

由于将模型传递给序列化器而不是字典而导致出现此错误。 您可以使用.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)