37

我对BasePermissionDjango-rest-framework 中的内容感到困惑。

这里我定义了一个类:IsAuthenticatedAndOwner.

class IsAuthenticatedAndOwner(BasePermission):
    message = 'You must be the owner of this object.'
    def has_permission(self, request, view):
        print('called')
        return False
    def has_object_permission(self, request, view, obj):
        # return obj.user == request.user
        return False

使用在views.py

class StudentUpdateAPIView(RetrieveUpdateAPIView):
    serializer_class = StudentCreateUpdateSerializer
    queryset = Student.objects.all()
    lookup_field = 'pk'
    permissions_classes = [IsAuthenticatedAndOwner]

但它根本不起作用。每个人都可以通过权限并更新数据。

called没有打印出来。


我曾经定义过这个类:IsNotAuthenticated

class IsNotAuthenticated(BasePermission):
    message = 'You are already logged in.'
    def has_permission(self, request, view):
        return not request.user.is_authenticated()

它在功能中运行良好

class UserCreateAPIView(CreateAPIView):
    serializer_class = UserCreateSerializer
    queryset = User.objects.all()
    permission_classes = [IsNotAuthenticated]

has_object_permission那么,上面的例子和函数&有什么区别has_permission呢?

4

3 回答 3

50

我们在BasePermission类上有以下两种权限方法:

  • def has_permission(self, request, view)
  • def has_object_permission(self, request, view, obj)

调用这两种不同的方法来限制未经授权的用户进行数据插入和操作。

has_permission在所有 HTTP 请求上has_object_permission调用,而从 DRF 的方法调用def get_object(self)。因此,has_object_permission方法可用于GET, PUT, DELETE, 不适用于POST请求。

总之:

  • permission_classes在定义的列表上循环。
  • has_object_permissionhas_permission方法在方法返回值后调用,True除了在 POST 方法中(POST仅在方法has_permission中执行)。
  • 当方法False返回一个值时permission_classes,请求没有权限,不会再循环,否则,它会检查所有循环的权限。
  • has_permission方法将在所有 ( GET, POST, PUT, DELETE)HTTP请求上调用。
  • has_object_permission方法不会被HTTP POST请求调用,因此我们需要从has_permission方法中限制它。
于 2018-04-03T09:07:55.810 回答
24

基本上,第一个代码否认一切,因为has_permission返回 False。

has_permission是在调用has_object_permission. 这意味着在您有机会检查所有权测试之前,您需要获得允许。has_permission

你想要的是:

class IsAuthenticatedAndOwner(BasePermission):
    message = 'You must be the owner of this object.'
    def has_permission(self, request, view):
        return request.user and request.user.is_authenticated
    def has_object_permission(self, request, view, obj):
        return obj.user == request.user

这也将允许经过身份验证的用户创建新项目或列出它们。

于 2017-03-28T13:23:49.127 回答
1

我认为这会有所帮助:

class IsAuthorOrReadOnly(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        # Read-only permissions are allowed for any request
        if request.method in permissions.SAFE_METHODS:
            return True
        # Write permissions are only allowed to the author of a post
        return obj.user == request.user
于 2021-02-02T16:10:34.040 回答