I have the following viewset:
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()
As seen, Im trying to allow the 'create' method without allowing the 'list', for an Authenticated user (which is not an admin). Weirdly, this Viewset results no create nor list for the Authenticated user. Iv'e checked, just to rull off, the following code:
class RouteOrderingDetail(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
mixins.UpdateModelMixin,
viewsets.GenericViewSet):
queryset = RouteOrdering.objects.all()
serializer_class = RouteOrderingSerializer
This did allowed for a view in which there is create but not list (but its not usable for me, since i do need the list option avilable.
Hope the problem is clear. Any help will be appriciated.
I realize this has already been answered, but wanted to share my implementation in case it better suits the OPS use case, or someone else's:
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)
Hopefully this help's someone out :)
Maybe you can try this:
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
....
The reference: Allow separate permissions per View in ViewSet
Also, you might want to check out this questions which is very similar to yours: Separate permissions per methods
OR
you can do it like this:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With