DRF:始终应用默认权限类别

问题描述 投票:0回答:3

在视图中定义权限时,我想始终检查请求用户是否具有该权限。

假设我有这样的基本权限检查:

class HasPermission(permissions.BasePermission):

    def has_permission(self, request, view, obj=None):
        if hasattr(view, 'permission_required'):
            return request.user.has_perm(view.permission_required)
        return True

我已将其添加为我的

settings
中的默认权限:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
    'DEFAULT_PERMISSION_CLASSES': [
        'apps.api.permissions.HasPermission'
    ],
}

这是可行的,但是一旦我在视图中定义了

permission_classes
,默认值就会被覆盖。有没有干净且正确的方法来做到这一点?我可能可以编写一个 Mixin 并在
dispatch
中执行相同的操作,但想使用推荐的
Permission
类。

django django-rest-framework permissions
3个回答
0
投票

权限属性采用类列表,因此您只需包含默认值即可。

class ModelViewSet(viewsets.ModelViewSet):
    permission_classes = (
        DefaultPermission,
        CustomPermission,
    )

0
投票
仅当您未在视图集中声明

permission_classes

 时,才会应用 
DEFAULT_PERMISSION_CLASSES。

如果您没有任何其他需要申请的权限类别,只需从您的视图集中排除

permission_classes
,这样它将始终使用默认值。

如果有时您需要使用其他权限类别以及默认权限类别。

例如

class HasPermission(permissions.BasePermission):

    def has_permission(self, request, view, obj=None):
        if hasattr(view, 'permission_required'):
            return request.user.has_perm(view.permission_required)
        return True

class AnotherPermissionClass(..):
    ....

其中

HasPermission
始终需要应用,有时可能还需要应用 AnotherPermissionClass`。

如果是这种情况,那么只需继承

HasPermission
作为
AnotherPermissionClass
的基类即可。


AnotherPermissionClass(apps.api.permissions.HasPermission)
     def has_permmision(self, request, view, obj=None):
         has_base_perm = super().has_permmision(request, view, obj=obj)
         ...

class ViewsetA(...):
     ...

     # Don't declare permission_classes at all and it will use the settings default


class ViewsetB(...):
     permission_classes = (AnotherPermissionClass,)

0
投票
  1. 更简单的方法是将任何新权限附加到默认类。

这更加灵活,因为根据项目的不同,将来可能会有一组完全不同的 API(或者可能根本没有)。

permission_classes

您可以创建一个辅助函数,以便更容易使用

from rest_framework import permissions from rest_framework.settings import api_settings class MyView(viewsets.ModelViewSet): permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES + [permissions.IsAdminUser]

探索扩展用于身份验证的中间件或实现将运行默认权限类的
    自定义中间件
  1. 。如果您希望它变得更加灵活,您可以在视图中定义一个类属性,例如from rest_framework import permissions from rest_framework.settings import api_settings def init_perms(new_classes: list) -> list: return api_settings.DEFAULT_PERMISSION_CLASSES + new_classes class MyView(viewsets.ModelViewSet): permission_classes = init_perms([permissions.IsAdminUser]) 并从中间件读取视图类属性以了解是否运行默认的。
    
        
© www.soinside.com 2019 - 2024. All rights reserved.