idi*_*dik 3 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']:
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()
Run Code Online (Sandbox Code Playgroud)
如图所示,我试图为Authenticated用户(不是管理员)允许'create'方法而不允许'list'。奇怪的是,此Viewset不会为Authenticated用户创建或列出任何结果。我检查了一下,以弄清下面的代码:
class RouteOrderingDetail(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
mixins.UpdateModelMixin,
viewsets.GenericViewSet):
queryset = RouteOrdering.objects.all()
serializer_class = RouteOrderingSerializer
Run Code Online (Sandbox Code Playgroud)
这确实允许在其中创建但没有列表的视图(但它对我不可用,因为我确实需要可用的列表选项。
希望问题解决。任何帮助将被申请。
blu*_*oro 11
也许你可以试试这个:
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
....
Run Code Online (Sandbox Code Playgroud)
此外,您可能想查看与您的问题非常相似的问题:Separate permissions per methods
或者
你可以这样做:
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
Run Code Online (Sandbox Code Playgroud)
我意识到已经解决了这个问题,但是想分享我的实现,以防它更适合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)
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助某人:)
| 归档时间: |
|
| 查看次数: |
4252 次 |
| 最近记录: |