16

I'm reading http://www.django-rest-framework.org/api-guide/permissions/ and trying to relate it to the OAuth2 toolkit documentation, http://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html. The latter has an example in which in settings.py one specifies

REST_FRAMEWORK = {
    # ...

    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

and in addition, IsAuthenticated is also specified added to the permission_classes list of a ModelViewSet:

class UserViewSet(viewsets.ModelViewSet):
    permission_classes = [permissions.IsAuthenticated, TokenHasReadWriteScope]
    queryset = User.objects.all()
    serializer_class = UserSerializer

Do I infer correctly from this example that the DEFAULT_PERMISSION_CLASSES are not prepended / postpended to a ModelViewSet's permission classes, but are instead replaced by it?

Kurt Peek
  • 52,165
  • 91
  • 301
  • 526

4 Answers4

10

In the Django REST framework, how are the default permission classes combined with per-view(set) ones?

They are not combined.

... the DEFAULT_PERMISSION_CLASSES are not prepended / postpended to a ModelViewSet's permission classes, but are instead replaced by it?

Correct.

wim
  • 338,267
  • 99
  • 616
  • 750
8

Do I infer correctly from this example that the DEFAULT_PERMISSION_CLASSES are not prepended / postpended to a ModelViewSet's permission classes, but are instead replaced by it?

The DEFAULT_PERMISSION_CLASSES are used for views/viewsets where permission_classes is not defined. In the cases they are defined, those are used instead, not the default ones.

dukebody
  • 7,025
  • 3
  • 36
  • 61
3

If you do want to extend the default permissions, this seems to work.

Disclaimer: I found it by looking into DRF's code, not sure it is documented.

from rest_framework.settings import api_settings

class UserViewSet(viewsets.ModelViewSet):
    permission_classes = [*api_settings.DEFAULT_PERMISSION_CLASSES, TokenHasReadWriteScope]
Arnaud P
  • 12,022
  • 7
  • 56
  • 67
-1

Add code in your custom Permission class like this

class ObjectWritePermission(BasePermission):
    # you will see this function in IsAuthenticated Permission class
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated)

    def has_object_permission(self, request, view, obj):
        return obj.user == request.user