Warwick
Warwick

Reputation: 1230

Django REST framework: using object-level permissions without model-level permissions

I have a Django project with API based on the Django REST framework.

Recently I've enabled object-level permissions with the use of django-guardian. However I'm not using model-level permissions framework in my project yet (and until this moment I didn't see any purpose to.)

Now when I turn on DjangoObjectPermissions in my API viewset,

class PhotoViewSet(viewsets.ModelViewSet)
    permission_classes = (permissions.DjangoObjectPermissions,)

and make an update request to the endpoint for an object that has a proper "change" permission from the Guardian framework, I get a 403 FORBIDDEN response.

The reason for this response appears to lay in a request dispatch stage:

  1. DRF checks model permissions in this case.
  2. DjangoObjectPermissions inherits from DjangoModelPermissions.
  3. DRF calls DjangoObjectPermissions.has_permission()
  4. has_permission() fails because I'm not using model-level permissions.

What is a proper way to use DjangoObjectPermissions in my case?

Upvotes: 3

Views: 2010

Answers (1)

DjangoObjectPermissions is implemented in a way that expects a user to be able to edit a model as well as have permission to edit an instance of that model.

>>> from django.contrib.auth.models import User, Group
>>> user = User.objects.get(pk=1)
>>> admins = Group.objects.get(pk=1)
>>> user.has_perm('change_group')
False
>>> user.has_perm('change_group', admins)
True

Managing model permissions can add (user management) overhead to your project. I would suggest only going down this route if you have the requirement for the rest of your project and plan to use it.

Instead creating a custom permissions class that suits exactly your needs seems like the best course. It can be as simple as:

class ObjectOnlyPermissions(DjangoObjectPermissions):

    def has_permission(self, request, view):
        return True

The workaround you reference is undocumented and looks like it's there to solve an internal issue (APIRootView endpoint list being filtered). I wouldn't rely on this to fix your issue.

Upvotes: 4

Related Questions