Как реализовать 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 это нормально, так что просто объединить их в одном методе класса вьюсетс и на этом успокоиться.?