Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: How to limit model list access permission to its owner?

I have a django model and and i want that model to be accessed only by its owner(user who created the model). So i created a permission class as follows

class IsOwnerOnly(permissions.BasePermission):


def has_object_permission(self, request, view, obj):

    # Write permissions are only allowed to the owner of the snippet.
    return obj.owner == request.user

and applied this permission on modelviewset

class ItemViewSet(viewsets.ModelViewSet):

    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    permission_classes = (IsOwnerOnly,)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

While accessing a single item it works, But even then every authenticated user can access the list of items. So how could i limit the item access to only its owner?

I have included Tokenauthentication in settings page as shown

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (

    'rest_framework.authentication.TokenAuthentication',

),
}

and the item looks like

class Item(models.Model):

    name=models.CharField(max_length=30)
    address=models.TextField()
    owner = models.ForeignKey('auth.User', related_name='items', on_delete=models.CASCADE)

    def __str__(self):
        return self.name
like image 970
Hari Krishnan Avatar asked Sep 04 '25 17:09

Hari Krishnan


2 Answers

You can override the method get_queryset on your View

class ItemViewSet(viewsets.ModelViewSet):

    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    permission_classes = (IsOwnerOnly,)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

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

This way the method list (from ModelViewSet) will call your "get_queryset" to build the pagination with the data.

like image 73
Rafa Acioly Avatar answered Sep 06 '25 20:09

Rafa Acioly


You can't control who can access item list by owner,if you what,you need to override has_permission to class IsOwnerOnly, like:

class IsAuthenticatedOwner(permissions.BasePermission):
    def has_permission(self, request, view):
        # work when your access /item/
        if request.user and is_authenticated(request.user):
            if request.user.id in [1, 2, 3]:
                return True
            else:
                return False
        else:
            return False

    def has_object_permission(self, request, view, obj):
        # work when your access /item/item_id/
        # Instance must have an attribute named `owner`.
        return obj.owner == request.user

Notice:has_permission work when your access /item/(list),has_object_permission work when your access /item/item_id/(retrieve and update).

If you want to let user see the items only he created,simple as:

class ItemsViewSet(ModelViewSet):
    queryset = Items.objects.all()
    serializer_class = ItemsSerializer
    permission_classes = (IsAuthenticated)

    def get_queryset(self):
        queryset = self.get_queryset().filter(owner=self.request.user)
        return queryset
like image 43
Ykh Avatar answered Sep 06 '25 19:09

Ykh