我正在使用django restframework
来执行一些需要权限的工作。我想做的是在我的视图中要求整个权限,在我指定的方法中要求不同的权限。下面是我对一些主要代码的试用。
1个基本视图
class VSAccount(viewsets.ModelViewSet):
queryset = MAccount.objects.all().filter(active=True)
serializer_class = DEFAULT_ACCOUNT_SERIALIZER_CLASS
filter_backends = (SearchFilter, DjangoFilterBackend)
permission_classes = [IsAuthenticated, BaseDataPermission, ]
filter_class = FAccount
search_fields = []
module_perm = 'account.get_account'
# 1) add module_perm account.get_account required for whole view.
@action(methods=['get'], url_path='list-with-daily-spends', detail=False)
def list_daily_spend(self, request, *args, **kwargs):
self.module_perm = 'account.get_account-list-with-daily-spend'
# 2) add module_perm for this method only but doesn't work here
self.permission_classes = [BaseDataPermission, ]
self.serializer_class = SAccountListItemDaily
ret_data = super().list(request, *args, **kwargs)
self.serializer_class = DEFAULT_ACCOUNT_SERIALIZER_CLASS
return ret_data
2客户权限
class BaseDataPermission(BasePermission):
authenticated_users_only = True
def has_perms(self, user, perm):
user_perms = user.get_all_permissions()
print(perm) # it's always what I write in viewset?
if perm in user_perms:
return True
return False
def has_permission(self, request, view):
if request.user.is_superuser:
return True
assert hasattr(view, "module_perm"), "need module_perm"
assert isinstance(view.module_perm, str), "module_perm should be a string"
if getattr(view, '_ignore_model_permissions', False):
return True
if hasattr(view, 'get_queryset'):
queryset = view.get_queryset()
else:
queryset = getattr(view, 'queryset', None)
assert queryset is not None, (
'Cannot apply DjangoModelPermissions on a view that '
'does not set `.queryset` or have a `.get_queryset()` method.'
)
return (
request.user and
(request.user.is_authenticated or not self.authenticated_users_only) and
self.has_perms(request.user, view.module_perm)
)
我的问题是,为什么我在方法list_daily_spend
中重写moudle_perm
,所需的权限仍然是我在VSAccount
中写的account.get_account
,我如何才能得到预期的结果?
感谢
更改self.permission_classes
的值不会达到目的,您需要将ModelViewSet的get_permissions(...)
方法重写为,
class VSAccount(viewsets.ModelViewSet):
# rest of your code
def get_permissions(self):
if self.action == 'list_daily_spend':
self.module_perm = 'account.get_account-list-with-daily-spends'
permission_classes = [BaseDataPermission, ]
return [permission() for permission in permission_classes]
return super().get_permissions()
或者,您可以将action
装饰器中的权限类设置为,
class VSAccount(viewsets.ModelViewSet):
@action(methods=['get'],
url_path='list-with-daily-spends',
detail=False,
permission_classes=[BaseDataPermission, ], module_perm = 'account.get_account-list-with-daily-spends')
def list_daily_spend(self, request, *args, **kwargs):
# your code