Обновление объектов с помощью PATCH для Django REST Framework

Я использую viewsets.ModelViewSet

from rest_framework import viewsets

class ProjectViewSet(viewsets.ModelViewSet):
    serializer_class = s.ProjectSerializer   
    queryset = m.Project.objects.all()

    def patch(self,request,*args,**kwargs):
      instance = self.get_object()
      serializer = self.get_serializer(instance,data = request.data)
      if serializer.is_valid():
          self.perform_update(serializer)
          return Response(serializer.data)
      return Response()

Затем я тестирую обновление объекта через django restframework UI.

enter image description here

enter image description here

Тогда возникает эта ошибка.

Моя основная идея о том, что изменение данных объекта через PATCH правильно?

Как я могу обновить данные через Django REST Framework

?
Expected view ProjectViewSet to be called with a URL keyword argument named "pk". Fix your URL conf, or set the `.lookup_field` attribute on the view correctly.

Во-первых, проблема напрямую связана с настройкой URL, в любом случае я бы предложил использовать DRF маршрутизаторы :

from django.urls import path, include
from .views import ProjectViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'projects', ProjectViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
]

Во-вторых, действия, предоставляемые ModelViewSet - это .list(), .retrieve(), .create(), .update(), .partial_update() и .destroy().

Действие, связанное с PATCH, это partial_update, поэтому:

class ProjectViewSet(ModelViewSet):
    serializer_class = ProjectSerializer   
    queryset = Project.objects.all()

    def partial_update(self, request, *args, **kwargs):
        partial = True
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        return Response(serializer.data)

Оригинальный код UpdateModelMixin

.partial_update:

def partial_update(self, request, *args, **kwargs):
    kwargs['partial'] = True
    return self.update(request, *args, **kwargs)

Как вы можете видеть, он по-прежнему вызывает .update, который делает почти то же самое:

def update(self, request, *args, **kwargs):
    partial = kwargs.pop('partial', False)
    instance = self.get_object()
    serializer = self.get_serializer(instance, data=request.data, partial=partial)
    serializer.is_valid(raise_exception=True)
    self.perform_update(serializer)

    if getattr(instance, '_prefetched_objects_cache', None):
        # If 'prefetch_related' has been applied to a queryset, we need to
        # forcibly invalidate the prefetch cache on the instance.
        instance._prefetched_objects_cache = {}

    return Response(serializer.data)
Вернуться на верх