在drf

时间:2019-04-04 19:13:28

标签: django django-rest-framework

我正在尝试通过动作装饰器进行批量更新,但是会创建新数据。

我的例子:

@action(methods=['put'], detail=False)
    def car_update(self, request, *args, **kwargs):
        serializer = CarSerializer(data=request.data, many=True, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)

使用我的端点(/ api / car / car_update)创建一个新条目。

例如,我传递JSON:

[
    {
        "id" 2,
        "color": "blue",
        "amount": 3
    }
]

但是我收到一个新的消息:

[
    {
        "id" 3,
        "color": "blue",
        "amount": 3
    }
]

当我尝试传递实例时,像这样:

...
car = Car.objects.get()
        serializer = CarSerializer(instance=car, data=request.data, many=True, context={'request': request})

我收到了:

get() returned more than one Car -- it returned 13!

更新1

我的序列化器示例:

class GarageSerializer(serializers.ModelSerializer):

    class Meta:
        model = Garage
        fields = "__all__"

class CarSerializer(serializers.ModelSerializer):
    class Meta:
        model = Car
        fields = "__all__"

我的查看示例:

class GarageViewSet(viewsets.ModelViewSet):
    queryset = Garage.objects.all()
    serializer_class = GarageSerializer
    model = Garage

class CarViewSet(RestrictedQuerysetMixin, viewsets.ModelViewSet):
    queryset = Car.objects.all()
    serializer_class = CarSerializer
    model = Car

    @action(methods=['put'], detail=False)
        def car_update(self, request, *args, **kwargs):
            serializer = CarSerializer(data=request.data, many=True, context={'request': request})
            if serializer.is_valid():
                for instance in serializer.data:
                    Car.objects.get(id=instance['id']).update(**instance)
                return Response(serializer.data)

2 个答案:

答案 0 :(得分:1)

我从没使用过DRF,但是在Django中您不能这样做

car = Car.objects.get()

您需要执行类似的操作

car = Car.objects.get(id=..)

或除id = ..之外的其他内容仍会唯一标识您的汽车实例,因为.objects.get仅允许选择一个实例。这不要与REST'get'混淆,这是另一回事

答案 1 :(得分:1)

如果现在我能正确理解的话,您想通过在通过请求发送的数据中提供它们的ID来更新所有对象。所需的默认情况下未实现,因此,如果要为更多视图实现它,可以将此示例用作mixin:

    serializer = CarSerializer(data=request.data, many=True, context={'request': request})
        if serializer.is_valid():
            for instance in serializer.data:
                Car.objects.get(id=instance['id']).update(**instance)

无论如何,我建议您处理由于您要修改的ID不存在而引发的异常。