1

In the django admin interface, it is possible to specify permissions on each individual Model. The permission options for an example model Customer are:

  • Can add customer
  • Can change customer
  • Can delete customer
  • Can view customer

However, these permissions do not seem to apply to REST Framework API Views (rest_framework.viewsets.ModelViewSet), implemented for Customer as follows:

class CustomerViewSet(viewsets.ModelViewSet):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = '__all__'

I thought that by setting the DEFAULT_PERMISSION_CLASSES to DjangoModelPermissions these permissions would be reflected, but it does not:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.DjangoModelPermissions',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
}

Should the permissions defined in admin work in Views as well with these settings, should they not, and/or is there any way to make this happen? The benefit is that system administrators can easily define groups in the admin interface and tailor their permissions to their problem areas, so being able to define permissions in this way is very desireable. I have seen many other ways of implementing permissions, but they require from what I have seen a lot of customization on the View definitions in python.

Versions:

  • Django 2.2.9
  • djangorestframework 3.11.0
  • djangorestframework-simplejwt 4.4.0

1 Answer 1

6

For API views to check for groups and permissions, we can use DjangoModelPermission in our views.py as follows.

from rest_framework.permissions import DjangoModelPermissions

class CustomerViewSet(viewsets.ModelViewSet):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer
    permission_classes = (DjangoModelPermissions, )

It restricts POST, PUT and DELETE access but allows GET access. To restrict it also

from rest_framework.permissions import DjangoModelPermissions

class CustomDjangoModelPermissions(DjangoModelPermissions):
    def __init__(self):
        self.perms_map['GET'] = ['%(app_label)s.view_%       (model_name)s']


class CustomerViewSet(viewsets.ModelViewSet):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer
    permission_classes = (CustomDjangoModelPermissions, )
Sign up to request clarification or add additional context in comments.

1 Comment

Great! I wasn't aware it allowed GET access, so that's why I was confused. With your exact code I got an error like return [perm % kwargs for perm in self.perms_map[method]] - not enough arguments to format string, but was able to get it working with this answer: stackoverflow.com/questions/55504648/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.