5

安らかなプロジェクト(django-rest-frameworkを使用)でdjango-guardianを使用して、オブジェクトのアクセス許可を管理したいと思います。

私が欲しいもの:

  • 接続ユーザーが「add_modelname」権限を持っている場合にのみ、オブジェクトの作成を許可します。
  • 接続ユーザーがオブジェクトを作成するときに、「delete_modelname」および「change_modelname」パーミッションを設定します。
  • 接続ユーザーが「change_modelobject」権限を持っている場合にのみ、オブジェクトを編集できるようにします。
  • 接続ユーザーが「delete_modelobject」権限を持っている場合にのみ、オブジェクトを削除できるようにします。

私はこのコードでこれらのケースを管理しようとしています:

view.py

class ModelNameViewSet(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.

    Additionally we also provide an extra `highlight` action.
    """
    queryset = ModelName.objects.all()
    serializer_class = ModelNameSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, ModelNamePermission)

    def create(self, request, *args, **kwargs):
        assign_perm("change_modelname", request.user, self)
        assign_perm("delete_modelname", request.user, self)
        return super().create(request, *args, **kwargs)

パーミッション.py

class ModelNamePermission(permissions.BasePermission):
    """
    Custom permission to only allow owners of an object to edit it.
    """

    def has_permission(self, request, view):
        if request.method in ['GET']:
            return request.user.has_perm('view_modelname')        
        if request.method in ['POST']:
            return request.user.has_perm('add_modelname')
        if request.method in ['PUT', 'PATCH']:
            return request.user.has_perm('change_modelname')
        if request.method in ['DELETE']:
            return request.user.has_perm('delete_modelname')
        return False

    def has_object_permission(self, request, view, obj):         
        if request.method in ['GET']:
            return request.user.has_perm('view_modelname', obj)        
        if request.method in ['POST']:
            return request.user.has_perm('add_modelname', obj)
        if request.method in ['PUT', 'PATCH']:
            return request.user.has_perm('change_modelname', obj)
        if request.method in ['DELETE']:
            return request.user.has_perm('delete_modelname', obj)
        return False

最初に遭遇する問題は、次の行にエラーがあることです。

assign_perm("change_modelname", request.user, self)

エラー :

error: 'ModelNameViewSet' object has no attribute '_meta'

残りのコードは機能しないと思いますが、少なくとも私がやりたいことはわかります。

これらの特定のケースの例は見たことがありません。

編集:もう1つのことは、このコードです:

request.user.has_perm('view_coachingrequest')

常に true を返します。しかし、私はこの権限を自分のユーザーに設定したことはありません(管理者ユーザーでのみ試しました。おそらくそれが理由です)。

4

1 に答える 1

2

ビューセットのcreateメソッドは、新しく作成されたモデル インスタンスを返します。ビューセット オブジェクト自体に権限を割り当てようとしています。createメソッドのコードは次のようになります。

def create(self, request, *args, **kwargs):
    instance = super().create(request, *args, **kwargs)
    assign_perm("change_modelname", request.user, instance)
    assign_perm("delete_modelname", request.user, instance)
    return instance

これにより、モデル インスタンスが作成され、必要なアクセス許可が割り当てられてから返されます。

于 2017-05-22T12:10:09.687 に答える