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

M1n*_*zwy 10 python django django-rest-framework

我对BasePermissionDjango-rest框架感到困惑.

在这里我定义了一个类: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
Run Code Online (Sandbox Code Playgroud)

在...中使用 views.py

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

但它根本不起作用.每个人都可以传递权限并更新数据.在called未打印.


我曾经定义过这个类: IsNotAuthenticated

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

它在该功能中运行良好

class UserCreateAPIView(CreateAPIView):
    serializer_class = UserCreateSerializer
    queryset = User.objects.all()
    permission_classes = [IsNotAuthenticated]
Run Code Online (Sandbox Code Playgroud)

那么,上面的例子和函数has_object_permission&之间的区别是什么has_permission

Lin*_*via 11

基本上,第一个代码拒绝一切因为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
Run Code Online (Sandbox Code Playgroud)

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

  • DRF 文档对此进行了解释。`has_permission` 是一个“通用”权限检查,用于查看请求是否满足某些条件。`has_object_permission` 更具体并链接到特定实例。 (2认同)

Rai*_*nod 10

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

  • def has_permission(自己,请求,查看)
  • def has_object_permission(self,request,view,obj)

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

has_permission在所有HTTP请求has_object_permission上调用,而从Django DRF方法调用def get_object(self)。因此,has_object_permission方法是可用的GETPUTDELETE,不为POST请求。

综上所述:

  • permission_classes 遍历已定义的列表。
  • has_object_permissionhas_permission方法返回值后,True除POST方法外(has_permission仅在POST方法中执行),将调用method方法。
  • False值从返回的permission_classes方法,请求获得许可,但不会循环更多,否则,它会检查循环的所有权限。
  • has_permission方法将在所有(称为GETPOSTPUTDELETEHTTP请求。
  • has_object_permission方法不会在请求时被调用,因此我们需要限制它。HTTP POSThas_permission