FACode
FACode

Reputation: 1061

Django Rest Framework owner permissions

I use Django Rest Framework and in my one of my viewsets class I have partial_update method (PATCH) for update my user profile. I want to create a permission for one user can update only his profile.

class ProfileViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows profiles to be viewed, added,
deleted or edited
"""
queryset = Profile.objects.all()
# serializer_class = ProfileSerializer
permission_classes = (IsAuthenticated,)
http_method_names = ['get', 'patch']

def get_queryset(self):
    user = self.request.user
    return self.queryset.filter(user=user)

def get_serializer_class(self):
    if self.action == 'list':
        return ListingMyProfileSerializer
    if self.action == 'retrieve':
        return ListingMyProfileSerializer
    if self.action == 'update':
        return ProfileSerializer
    return ProfileSerializer

def get_permissions(self):
    # Your logic should be all here
    if self.request.method == 'GET':
        self.permission_classes = (IsAuthenticated,)
    if self.request.method == 'PATCH':
        self.permission_classes = (IsAuthenticated, IsOwnerOrReject)
    return super(ProfileViewSet, self).get_permissions()

def partial_update(self, request, pk=None):
    ...
    ...

Now one user can update his profile and any other profile. I tried to create a permission class: IsOwnerOrReject but I don't know exactly what I must to do.

Upvotes: 6

Views: 14135

Answers (2)

aman kumar
aman kumar

Reputation: 3156

IsOwnerOrReject is permission class that match the user to current login user otherwise it rejects.

In your case you have to define custom permission class. Which check user is login for other profile what ever permission you want to apply. You can do it like this:

from django.contrib.auth.models import User ## Default Django User Model

class IsUpdateProfile(permissions.BasePermission):

      def has_permission(self, request, view):
           if more_condition: ## if have more condition then apply
              return True
           return request.user == User.objects.get(pk=view.kwargs['id'])
           
           

Upvotes: 5

Rieljun Liguid
Rieljun Liguid

Reputation: 1531

You can add a custom permission that checks whether it's his own profile. Something like this.

# permissions.py
from rest_framework import permissions
class OwnProfilePermission(permissions.BasePermission):
    """
    Object-level permission to only allow updating his own profile
    """
    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # obj here is a UserProfile instance
        return obj.user == request.user


# views.py
class ProfileViewSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated, OwnProfilePermission,)

UPDATE: You can remove the def get_permissions(self): part.

You can check the documentation for more info.

Upvotes: 11

Related Questions