from rest_framework import permissions
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
class MyPermission(permissions.BasePermission):
def has_permission(self, request, view):
return True
class MyViewSet(viewsets.GenericViewSet):
permission_classes = (permissions.IsAuthenticated,)
@action(detail=True, permission_classes=[MyPermission])
def test(self, request, *args, **kwargs):
return Response(status.HTTP_204_NO_CONTENT)
@action(detail=True)
def test2(self, request, *args, **kwargs):
return Response(status.HTTP_204_NO_CONTENT)
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls')),
url(r'^api/test/$', MyViewSet.as_view(actions={'get': 'test'})),
url(r'^api/test2/$', MyViewSet.as_view(actions={'get': 'test2'})),
]
When tracing the framework code only IsAuthenticated is referred to because it is set in the MyViewSet class instance permission_classes variable. MyPermission.has_permission is never called.
Framework code change suggestion
If the built-in rest_framework.views.APIView.get_permissions function was changed to the following it would automatically support the permissions_classes attribute of @action and if that was not specified then default's to MyViewSet().permission_classes in my example.
def get_permissions(self):
func_actions = {
action_details.url_name: action_details.kwargs.get(
'permission_classes'
) for action_details in self.get_extra_actions()
}
perm_classes = func_actions.get(self.action) or self.permission_classes
return [permission() for permission in perm_classes]
Can anyone tell me if either the documentation is wrong, the framework code does not match the documentation or I've misunderstood something here?
Assuming I haven't misunderstood, does anyone think that the code change suggestion is worth mentioning to the DRF developers?
Cheers
Del