簡體   English   中英

django rest 框架中對 ModelViewSet 的 PATCH 請求 - 如何實現 serializer.update()?

[英]PATCH request to ModelViewSet in django rest framework - how do I implement serializer.update()?

我正在嘗試使用ModelViewSet為我的產品 API 實現PATCH處理。 ( Product 實例主鍵是uuid ,因此uuid在下面的代碼中顯示為lookup_field )。

我對如何覆蓋update() ModelSerializer 類方法感到困惑。 源代碼中的存根如下所示:

def update(self, instance, validated_data):
    raise NotImplementedError('`update()` must be implemented.')

我不明白為什么應該提供instancevalidated_data ,因為它們應該是序列化程序根據其實例化的屬性: get_serializer(self, instance=None, data=None, many=False, partial=False) (向上滾動一個文檔中的段落)。 為什么我要提供經過驗證的數據? 序列化程序不應該驗證它嗎?

這是我的partial_update()實現:

product.py(視圖集類)

def get_object(self, uuid=None):
    """ Utility method to get the object """
    # authentication logic, returns None if object not found

def partial_update(self, request, uuid=None):
    instance = self.get_object(uuid)
    if not instance:
        return Response(status=status.HTTP_404_NOT_FOUND)
    serializer = self.get_serializer(instance, 
                    data=request.data,
                    many=isinstance(request.data, list),
                    partial=True)
    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    serializer.update() #NOT WORKING; NEEDS ARGS instance, validated_data
    return Response(serializer.data, status=status.HTTP_200_OK)

序列化程序.py

def update(self, instance, validated_data):
    # we link up the user foreign key here
    user=User.objects.filter(email=validated_data.pop('user', None)).first()
    if user:
        instance.fk_user = user

    #specify which fields to update, otherwise save() tries to SQL SET all fields
    update_fields = [k for k in validated_data]
    if user:
        update_fields.append('fk_user')
    for k,v in validated_data.items():
        setattr(instance, k, v)
    instance.save(update_fields=update_fields)
    return instance

這是一個很好且明智的問題。

關鍵是如果沒有提供instancevalidated_data ,我們會有很多關於如何訪問它們的問題,加上一些與create vs update混淆(它們將具有相同的簽名,為什么不只制作一個)。

但是,您不應該直接調用序列化程序的createupdate !!

您只需要調用serializer.save()它將執行路由以createupdate

即替換:

serializer.update() #NOT WORKING; NEEDS ARGS instance, validated_data

serializer.save()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM