DRF中has_object_permission和has_permission之间的区别是什么:权限?

时间:2017-03-28 08:29:01

标签: python django django-rest-framework

我对Django-rest-framework中的BasePermission感到困惑。

我在这里定义了一个类: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之间的区别是什么?

3 个答案:

答案 0 :(得分:9)

基本上,第一个代码拒绝所有内容,因为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

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

答案 1 :(得分:5)

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

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

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

在所有HTTP请求上调用

has_permission ,而从Django DRF方法 def get_object(self) 调用has_object_permission。因此, has_object_permission 方法可用 GET PUT {{1} } ,不适用于 DELETE 请求。

总结:

  • POST 循环定义列表。
  • permission_classes 方法返回值 has_object_permission 之后调用
  • has_permission 方法,但POST方法除外(仅在POST方法 True 中执行)。
  • has_permission 方法返回 False 值时,请求无权限且不会循环更多,否则会检查所有关于循环的权限。
  • permission_classes 方法将被调用( has_permission GET POST PUT DELETE 请求。
  • has_object_permission方法不会在 HTTP HTTP 请求中调用,因此我们需要从 {{1}限制它方法。

答案 2 :(得分:2)

我认为这会有所帮助:

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