georoot
georoot

Reputation: 3617

django rest framework permission 'isAdminorReadonly'

I want only admin to add content to model but that can be read by anyone. Is there any existing permission class that i can use for the same. Or what will be the best approach without object level permissions.Code for the same is

class TagList(generics.ListCreateAPIView):
    serializer_class = TagSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('title',)
    def get_queryset(self):
        return Tag.objects.all()

Upvotes: 7

Views: 6544

Answers (5)

timotaoh
timotaoh

Reputation: 330

I tried Ansuman's answer, and still wasn't able to use SAFE_METHODS without credentials because it inherits IsAdminUser. I inherited the BasePermission instead and incorporated the IsAdminUser functionality:

class IsAdminOrReadOnly(BasePermission):

    def has_permission(self, request, view):

        if request.method in SAFE_METHODS:
            return True

        return bool(request.user and request.user.is_staff)

Upvotes: 1

LeOverflow
LeOverflow

Reputation: 379

You can create a custom permissions say:

from rest_framework.permissions import BasePermission, IsAdminUser, SAFE_METHODS

class ReadOnly(BasePermission):
    def has_permission(self, request, view):
        return request.method in SAFE_METHODS

And then call the permission

class TagList(generics.ListCreateAPIView):
    serializer_class = TagSerializer
    # Supports Boolean operator 'or': |
    permission_classes = [
        IsAdminUser|ReadOnly
     ]
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('title',)
    def get_queryset(self):
        return Tag.objects.all()

https://www.django-rest-framework.org/api-guide/permissions/

Hope that helps ;)

Upvotes: 1

faran
faran

Reputation: 49

you can use

permission_classes = [permissions.IsAdminUser, permissions.IsAuthenticatedOrReadOnly]

this will let the admin to POST, DELETE, PUT, PATCH, GET. and for a authenticated or anonymous user only GET is allowed

Upvotes: 2

Ansuman Bebarta
Ansuman Bebarta

Reputation: 7246

Let's be specific to your questions.

  1. Is there any existing permission class that i can use for the same?

Ans: No. There is no permission provided by drf (till version 3) to provide full access to admin and readonly to anyone (I believe anonymous as well).

  1. What will be the best approach without object level permissions?

Ans: I would suggest to have a custom view level permission as follows:

from rest_framework.permissions import IsAdminUser, SAFE_METHODS

class IsAdminUserOrReadOnly(IsAdminUser):

    def has_permission(self, request, view):
        is_admin = super(
            IsAdminUserOrReadOnly, 
            self).has_permission(request, view)
        # Python3: is_admin = super().has_permission(request, view)
        return request.method in SAFE_METHODS or is_admin

Upvotes: 10

Rahul Gupta
Rahul Gupta

Reputation: 47866

Yes, there is an existing permission class DjangoModelPermissionsOrAnonReadOnly which you can use.

It will grant authorization if the user is authenticated and has the relevant object permissions assigned but will also allow unauthenticated users to have read-only access to the API.

class TagList(generics.ListCreateAPIView):
    ...
    # add both permission classes 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, permissions.DjangoModelPermissionsOrAnonReadOnly,)

From DRF documentation:

DjangoModelPermissions
This permission class ties into Django's standard django.contrib.auth model permissions. This permission must only be applied to views that has a .queryset property set. Authorization will only be granted if the user is authenticated and has the relevant model permissions assigned.

POST requests require the user to have the add permission on the model.
PUT and PATCH requests require the user to have the change permission on the model.
DELETE requests require the user to have the delete permission on the model.

DjangoModelPermissionsOrAnonReadOnly
Similar to DjangoModelPermissions, but also allows unauthenticated users to have read-only access to the API.

Upvotes: 9

Related Questions