Пользовательское разрешение DRF: разрешить «получение», запретить «список»

#django-rest-framework #django-views #django-permissions

Вопрос:

tldr: Я хочу создать разрешение, которое позволяет выполнять действие «извлечение», но не «список».

Я пишу REST API с использованием платформы Django Rest и столкнулся с проблемой создания пользовательских разрешений (для просмотра из наборов представлений.ModelViewSet)

Застрял при создании конечной точки, которая должна возвращать пользователей сайта:

-Администратор должен иметь разрешение на доступ к каждому методу

-Обычный пользователь должен иметь возможность «извлекать» и «исправлять» только свою собственную учетную запись

Я не могу найти способ отличить «список» запроса на получение от «извлечения». Проверка request.method == GET позволяет использовать их обоих, но я не хочу, чтобы пользователь мог перечислять всех других пользователей.

     from rest_framework.permissions import BasePermission

    ```

    def is_superuser(request):
         return request.user.is_superuser
        
    ```

    class IsAdminOrReadOnlyOwner(BasePermission):
        def has_permission(self, request, view):
            if is_superuser(request):
                return True
            else:
                return request.method in ['GET', 'PATCH']
        
        def has_object_permission(self, request, view, obj):
            is_owner_and_safe = int(request.user.id) == obj.id and request.method in ['GET', 'PATCH']
            return is_owner_and_safe or is_superuser(request)
 

Есть ли способ сделать это, все еще используя ModelViewSet?

Ответ №1:

При проверке разрешений Django Rest передает представление методам класса разрешений, и из представления вы можете определить действие. Вы можете увидеть пример для has_object_permission и RetrieveAPIView в исходном коде здесь.

Вы можете использовать view.action для идентификации действия методы класса разрешений, например:

 def has_permission(self, request, view):
    if is_superuser(request):
        return True
    else:
        return view.action in ['retrieve', 'update']
 

Вы можете зарегистрироваться view.action , has_object_permission чтобы получить то, что вы хотите.

Ответ №2:

Попробуйте использовать self.action метод в своем миксине. Это даст вам список, извлечение, обновление, уничтожение по мере того, как вы будете действовать,

Комментарии:

1. Хм, я хотел бы иметь разрешение «подключи и играй», которое я мог бы вставить в поле зрения, например permission_classes = [IsAdminOrReadOnlyOwner] . Значит, нет способа сделать это на 100% внутри класса разрешений?