Python Django Rest framework视图集权限”;创建;没有「;列表“;
我有以下视图集:Python Django Rest framework视图集权限”;创建;没有「;列表“;,python,django,permissions,django-rest-framework,Python,Django,Permissions,Django Rest Framework,我有以下视图集: class ActivityViewSet(viewsets.ModelViewSet): queryset = Activity.objects.all() serializer_class = ActivitySerializer def get_permissions(self): if self.action in ['update','partial_update','destroy','list']:
class ActivityViewSet(viewsets.ModelViewSet):
queryset = Activity.objects.all()
serializer_class = ActivitySerializer
def get_permissions(self):
if self.action in ['update','partial_update','destroy','list']:
self.permission_classes = [permissions.IsAdminUser,]
elif self.action in ['create']:
self.permission_classes = [permissions.IsAuthenticated,]
else :
self.permission_classes = [permissions.AllowAny,]
return super(self.__class__, self).get_permissions()
如图所示,对于经过身份验证的用户(不是管理员),我尝试在不允许“列表”的情况下允许“创建”方法。
奇怪的是,这个视图集不会为经过身份验证的用户创建或列出任何内容。
Iv'e检查,只是为了关闭,以下代码:
class RouteOrderingDetail(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
mixins.UpdateModelMixin,
viewsets.GenericViewSet):
queryset = RouteOrdering.objects.all()
serializer_class = RouteOrderingSerializer
此不允许使用创建但不包含列表的视图(但对我来说不可用,因为我确实需要列表选项Available)
希望问题清楚。我们将提供任何帮助。也许您可以尝试以下方法:
class NotCreateAndIsAdminUser(permissions.IsAdminUser):
def has_permission(self, request, view):
return (view.action in ['update', 'partial_update', 'destroy', 'list']
and super(NotCreateAndIsAdminUser, self).has_permission(request, view))
class CreateAndIsAuthenticated(permissions.IsAuthenticated):
def has_permission(self, request, view):
return (view.action == 'create'
and super(CreateAndIsAuthenticated, self).has_permission(request, view))
class NotSafeMethodAndAllowAny(permissions.AllowAny)
def has_permission(self, request, view):
return (view.action is not in ['update', 'partial_update', 'destroy', 'list', 'create']
and super(NotSafeMethodAndAllowAny, self).has_permission(request, view))
class ActivityViewSet(viewsets.ModelViewSet):
queryset = Activity.objects.all()
serializer_class = ActivitySerializer
permission_classes = (NotCreateAndIsAdminUser, CreateAndIsAuthenticated, NotSafeMethodAndAllowAny)
def create(self, request):
pass
def list(self, request):
pass
....
参考资料:
此外,您可能想查看与您的问题非常相似的问题:
或
您可以这样做:
class ActivityViewSet(viewsets.ModelViewSet):
queryset = Activity.objects.all()
serializer_class = ActivitySerializer
def get_permissions(self):
if self.action in ['update', 'partial_update', 'destroy', 'list']:
# which is permissions.IsAdminUser
return request.user and request.user.is_staff
elif self.action in ['create']:
# which is permissions.IsAuthenticated
return request.user and is_authenticated(request.user)
else :
# which is permissions.AllowAny
return True
我意识到这已经得到了回答,但我想分享我的实现,以防它更适合OPS用例,或其他人的:
from rest_framework.authentication import TokenAuthentication, SessionAuthentication
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.viewsets import ReadOnlyModelViewSet
from ..models import MyModel
from .serializers import MyModelSerializer
class ActionBasedPermission(AllowAny):
"""
Grant or deny access to a view, based on a mapping in view.action_permissions
"""
def has_permission(self, request, view):
for klass, actions in getattr(view, 'action_permissions', {}).items():
if view.action in actions:
return klass().has_permission(request, view)
return False
class MyModelViewSet(ReadOnlyModelViewSet):
serializer_class = MyModelSerializer
queryset = MyModel.objects.all()
permission_classes = (ActionBasedPermission,)
action_permissions = {
IsAuthenticated: ['update', 'partial_update', 'destroy', 'list', 'create'],
AllowAny: ['retrieve']
}
authentication_classes = (TokenAuthentication, SessionAuthentication)
希望此帮助是有人提供的:)检查如何创建自定义权限我确实创建了自定义权限,您可以在代码中清楚地看到这一点。问题超出此范围。您没有创建自定义权限类。您已经在视图集中编辑了
get\u permissions
方法。自定义权限类允许您根据请求返回权限。方法
以及如何创建自定义权限类?我已经试过了,但没有找到任何例子。班级应该在哪里?我如何引用它?等等。我实际上是这样检查的——它也不允许。我相信权限\u类装饰器只能在函数视图上使用。仍然不起作用。在为列表添加权限类:@permission\u classes((IsAdmin,))后,“创建”操作将不适用于经过身份验证的用户。@idik实际上,adamfc的评论是正确的,很抱歉我的错误。事实证明,您的想法是正确的,覆盖了def get_permissions()方法。但是,您需要以稍微不同的方式实现它。效果很好-APIView存在问题,因为在循环中如果操作中的view.action:
,则view.action对于选项查询是None。我刚刚添加了elif view.action为None:return True
以始终允许选项显示为可能。您还需要将“元数据”
添加到至少您的IsAuthenticated
列表中。阻止选项有点奇怪。