pythondjango-modelsdjango-rest-frameworkdjango-viewspermissions

Specific permissions for different types of users with django rest framework model and view


I'm using DRF's ModelViewSet for my views and DefaultRouter to create the urls.

This particular model creates a feature that only admins have full CRUD access.

Authenticated users should have READONLY and Delete permissions. And Anonymous users should only have READONLY access.

I'm pretty sure that I understand that is_staff set to True takes care of any admin permissions for CRUD access in django admin. I'm just not sure how to set up the Anonymous and Authenticated user permissions in the Model and View.

How can I setup these particular permissions for the different types of users? Does this setup require specific Model and View permissions?


Solution

  • Some of the permissions you want are already supported. For others, you can define your own permission classes. However, you can't just include all of the permissions classes in the list - you need to OR them together. Otherwise, the list of permissions will be implicitly treated as an AND operation.

    Here's the approach I would suggest. All of the below classes are lightly modified examples from either the DRF source code or the DRF docs. (Warning, the code below was not tested.)

    from rest_framework import permissions
    
    
    class IsAuthenticatedAndAllowed(permissions.BasePermission):
        """
        The request is authenticated as a user, and is an allowed operation for ordinary users.
        """
    
        def has_permission(self, request, view):
            safe_methods_plus_delete = ('GET', 'HEAD', 'OPTIONS', 'DELETE')
            return bool(
                request.method in safe_methods_plus_delete and
                request.user and
                request.user.is_authenticated
            )
    
    
    class IsReadOnly(permissions.BasePermission):
        """
        The request is a read-only request.
        """
    
        def has_permission(self, request, view):
            return bool(
                request.method in permissions.SAFE_METHODS
            )
    
    
    class MyCoolViewSet(viewsets.ModelViewSet):
        # ...
        permission_classes = [permissions.IsAdminUser | IsAuthenticatedAndAllowed | IsReadOnly]
        # ...