Как реализовать PUT и PATCH в django-rest-framework?

Итак, по ТЗ необходимо реализовать, кроме прочего CRUD, PUT и PATCH функционал.
PUT и PATCH должны работать по урлу с Primary Key, т.е. path('users/str:pk/', UserViewSet.as_view(),...

Во views.py UserViewSet(...) отвечает за весь CRUD

вот выдержка из него:

class UserViewSet(ListAPIView):

permission_classes = [IsAuthenticated, ]

'''
другие методы get, post, delete
'''
    def patch(self, request, **kwargs):
        pk = kwargs['pk']
        data = request.data
        saved_user = CustomUser.objects.get(pk=pk)
        serializer = WriteOnlyUserSerializer(instance=saved_user, data=data, partial=True)

        if serializer.is_valid(raise_exception=True):
            saved_user = serializer.save()

            return Response({
                "success": f"User with username '{saved_user}' patched successfully"})
        return Response(serialiser.errors, status=status.HTTP_400_BAD_REQUEST)


    def put(self, request, format=None, **kwargs):
        pk = kwargs['pk']
        data = request.data
        saved_user = CustomUser.objects.get(pk=pk)
        serializer = WriteOnlyUserSerializer(saved_user, data=data, partial=True)

        if serializer.is_valid(raise_exception=True):
            saved_user = serializer.save()

            return Response({
                "success": f"User with username '{saved_user}' updated successfully"})
        return Response(serialiser.errors, status=status.HTTP_400_BAD_REQUEST)

Как видно, оба метода сейчас по сути идентичны и работают одинаково. Но PUT, в отличии от PATCH, должен перезаписывать модель полностью, т.е. если ему передать не все открытые для изменения поля модели, то они должны обновиться на пустые. в этом, как я понял, суть разницы PUT и PATCH.
В документации к DRF я нашел только такую реализацию PUT. Возможно плохо искал.

в serializers.py определены поля с которыми работаем:

class WriteOnlyUserSerializer(serializers.ModelSerializer):

    first_name = serializers.CharField(max_length=30)
    last_name = serializers.CharField(max_length=150)
    is_active = serializers.BooleanField()

    class Meta:
        model = CustomUser
        fields = [
            'username',
            'is_active',
            'first_name',
            'last_name',
            ]
        read_only = [
            'id',
            'last_login',
            'is_superuser',
        ]

Вопрос:
как написать метод PUT чтобы он работал корректно и не был copypast-ом PATCH, что как я понимаю бред.
Или же можно оба запроса провести в одном методе класса UserViewSet, просто проверяя какой запрос пришел put или patch. Но опять же как реализовать PUT.
или одинаковая работа PUT и PATCH это нормально, так что просто объединить их в одном методе класса вьюсетс и на этом успокоиться.?


Ответы (0 шт):