Я пишу API, используя фреймворк Django. остальное и мне интересно, если можно указать разрешения на метод, когда с помощью представлений, основанных класс.
Документации я вижу, что это довольно легко сделать, если вы пишете на основе функции вид, только с помощью @permission_classes
оформитель на себя функцию представления, которое вы хотите защитить с разрешения. Однако, я не'т вижу способа сделать то же самое, когда используя CBVs с APIView
класс, потому что тогда я задать разрешения для полного класса с permission_classes
атрибут, но что будет применена тогда все методы класса (вам
, пост
, положить
...).
Итак, это возможно, чтобы иметь мнение по API, написанный с CBVs, а также задать разные разрешения для каждого метода класса посмотреть?
Я'вэ столкнетесь с той же проблемой при использовании ЦБВ's, как у меня достаточно сложный разрешения логику в зависимости от запроса метода.
Решение, которое я придумал, чтобы использовать третье лицо 'rest_condition' приложение, перечисленных в нижней части этой страницы
http://www.django-rest-framework.org/api-guide/permissions
https://github.com/caxap/rest_condition
Я просто расколоть разрешения логику потока, так что каждый филиал будет работать, в зависимости от метода запроса.
from rest_condition import And, Or, Not
class MyClassBasedView(APIView):
permission_classes = [Or(And(IsReadOnlyRequest, IsAllowedRetrieveThis, IsAllowedRetrieveThat),
And(IsPostRequest, IsAllowedToCreateThis, ...),
And(IsPutPatchRequest, ...),
And(IsDeleteRequest, ...)]
Так что 'или' определяет, к какой отрасли права должны работать в зависимости от метода и 'и' обертывания разрешений, относящихся к запросу способ, так что все должно пройти для разрешения. Вы можете также смешать 'или', 'и' и 'Не' внутри каждого потока, чтобы создать еще более сложные разрешения.
Разрешение классы для выполнения каждой ветке просто выглядеть так,
class IsReadyOnlyRequest(permissions.BasePermission):
def has_permission(self, request, view):
return request.method in permissions.SAFE_METHODS
class IsPostRequest(permissions.BasePermission):
def has_permission(self, request, view):
return request.method == "POST"
... #You get the idea
Разрешения применяются ко всему классу смотреть, но вы можете учитывать различные аспекты запрос (например, метод GET или POST) в вашем решение об авторизации.
Смотрите в IsAuthenticatedOrReadOnly как пример:
SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']
class IsAuthenticatedOrReadOnly(BasePermission):
"""
The request is authenticated as a user, or is a read-only request.
"""
def has_permission(self, request, view):
if (request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated()):
return True
return False
Я столкнулся с этой проблемой и действительно хотел использовать @permission_classes
декоратор, чтобы отметить некоторые пользовательские методы просмотра с конкретными разрешениями. Я в конечном итоге придумывают миксинов:
class PermissionsPerMethodMixin(object):
def get_permissions(self):
"""
Allows overriding default permissions with @permission_classes
"""
view = getattr(self, self.action)
if hasattr(view, 'permission_classes'):
return [permission_class() for permission_class in view.permission_classes]
return super().get_permissions()
Пример варианта использования:
from rest_framework.decorators import action, permission_classes # other imports elided
class MyViewset(PermissionsPerMethodMixin, viewsets.ModelViewSet):
permission_classes = (IsAuthenticatedOrReadOnly,) # used for default ViewSet endpoints
queryset = MyModel.objects.all()
serializer_class = MySerializer
@action(detail=False, methods=['get'])
@permission_classes((IsAuthenticated,)) # overrides IsAuthenticatedOrReadOnly
def search(self, request):
return do_search(request) # ...
Я знаю, это старый вопрос, но я недавно столкнулся с такой же проблемой и хотел бы поделиться мое решение (так принято отвечать было'т достаточно, что мне было нужно). @GDorn'ы ответ поставил меня на правильный путь, но он работает только с ViewSet из-за себя.действия
Я'вэ ее решили создать свой собственный декоратор:
питон деф method_permission_classes(классы): деф декоратор(функции): деф decorated_func(самовыдвижение, *параметр args, **kwargs): самовывоз.permission_classes = классы возвратить кнопку func(самовыдвижение, *параметр args, **kwargs) возвращение decorated_func возвращение декоратор
Вместо того, чтобы устанавливать свойство permission_classes на функции, как встроенный, что делает декоратор, мой декоратор обертывания вызова и устанавливает классы полномочий на представление экземпляра, который вызывается. Таким образом, Нормаль get_permissions()
не'т необходимости каких-либо изменений, так что просто полагается на себя.permission_classes`.
Пример использования:
``питон из rest_framework видом импорт, разрешения
как myview класса(вид.APIView): permission_classes = (разрешения.IsAuthenticatedOrReadOnly,) # используется для конечных точек APIView по умолчанию объект QuerySet = MyModel.объекты.все() serializer_class = MySerializer
@method_permission_classes((разрешениями.IsAdminUser,)) # переопределяет IsAuthenticatedOrReadOnly деф удалить(самовыдвижение, запроса, идентификатор): экземпляр = собственн.get_object() # ... ``
Надеюсь, что это помогает кто-то бежит в ту же проблему!