Reputation: 1606
I am particularly interested in using ModelViewSet
for solving the challenge of updating the logged in user's profile. I am using the following definition:
from rest_framework import viewsets
class ProfileRetrieveUpdate(viewsets.ModelViewSet):
serializer_class = UserProfileSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get_queryset(self):
return UserProfile.objects.filter(user=self.request.user)
def perform_update(self, serializer):
serializer.save(user=self.request.user)
By overriding get_queryset
, I am able to get the expected behavior, i.e. when I access the endpoints (say profile/
), I get the profile of the logged in user. However, if I have to update the profile, I can only access PUT
by going to profile/6/
. Is there a way I can get ModelViewSet
to expose PUT
at the same endpoint i.e. profile/
?
Upvotes: 2
Views: 1955
Reputation: 6189
You can register ModelViewSet
HTTP method under any path you want.
path(
"profile",
ProfileRetrieveUpdate.as_view(
{"put": "partial_update", "get": "retrieve"}
),
name="profile-retrieve-update",
)
You will have to adjust other things as well as you don't provide pk
.
Instead of overriding get_queryset
method you need to adjust get_object
for your needs.
from rest_framework import viewsets
from rest_framework.generics import get_object_or_404
class ProfileRetrieveUpdate(viewsets.ModelViewSet):
serializer_class = UserProfileSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
queryset = UserProfile.objects.all()
def get_object(self):
obj = get_object_or_404(self.queryset, user=self.request.user)
self.check_object_permissions(self.request, obj)
return obj
def perform_update(self, serializer):
serializer.save(user=self.request.user)
Now if you PUT profile/
it should work as expected.
Upvotes: 1