Django rest framework : Prevent one user from deleting/Editing/Viewing other users in ModelViewSet

Issue

I was using Django users model for my Django rest framework. For this I used Django’s ModelViewSet for my User class.

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

Serializers.py

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'password']

        extra_kwargs = {
            'password' : {
                'write_only':True,
                'required': True
            }
        }
    
    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        Token.objects.create(user=user) # create token for the user
        return user

But currently from postman when I make the request using the token of one user to view, delete, edit other users

http://127.0.0.1:8000/api/users/4/

Its able to edit/delete/view other users. I don’t want that to happen and one user can make request on itself only is all I want.

This is my apps urls.py

urls.py

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


router = DefaultRouter()
router.register('articles', ArticleViewSet, basename='articles')
router.register('users', UserViewSet, basename = 'users')


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

How can I prevent one user from accessing other users when they make GET/POST/PUT/DELETE request.

EDIT 1: After adding the IsOwnerOfObject class as provided in he answers below, now when I am requesting the detail of the user himself, I am getting

Authentication credentials were not provided.

enter image description here

Solution

Building from Ene’s answer, authentication and permission classes needs to be provided.

Create a file named permissions.py.

from rest_framework import permissions

class IsOwnerOfObject(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        return obj == request.user

next add the permission and authentication class to ModelViewSet:

from api.permissions import IsOwnerOfObject
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    permission_classes = [IsAuthenticated, IsOwnerOfObject]
    authentication_classes = (TokenAuthentication,)

Answered By – Himanshu Poddar

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published