3

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?

  • (A) Implement a custom permission class, inherit it from DjangoObjectPermissions and override has_permission().
  • (B) Turn the Django's model-level permission framework on just for the sake of it.
  • (C) Use this hack workaround to skip the check.
4

1 に答える 1

4

DjangoObjectPermissionsユーザーがモデルを編集できること、およびそのモデルのインスタンスを編集する権限を持っていることを期待する方法で実装されています。

>>> 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

モデルのパーミッションを管理すると、(ユーザー管理の) オーバーヘッドがプロジェクトに追加される可能性があります。プロジェクトの残りの要件があり、それを使用する予定がある場合にのみ、このルートをたどることをお勧めします。

代わりに、ニーズにぴったり合うカスタム権限クラスを作成するのが最善の方法のようです。次のように簡単にできます。

class ObjectOnlyPermissions(DjangoObjectPermissions):

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

あなたが参照している回避策は文書化されておらず、内部の問題を解決するためにあるようです (APIRootView エンドポイント リストがフィルタリングされています)。あなたの問題を解決するためにこれに頼るつもりはありません。

于 2015-12-19T22:10:55.943 に答える