django has_object_permission和has_permission之间有什么区别?

jvlzgdj9  于 2023-01-27  发布在  Go
关注(0)|答案(5)|浏览(206)

我对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_permissionhas_permission有什么不同呢?

txu3uszq

txu3uszq1#

我们在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方法可用于GETPUTDELETE,而不用于POST请求。

    • 总结如下:**
  • permission_classes在定义的列表上循环。
  • has_permission方法返回值True后调用has_object_permission方法,POST方法除外(在POST方法中仅执行has_permission)。
  • 当从permission_classes方法返回False值时,请求不会获得任何权限,也不会再循环,否则,它将检查循环时的所有权限。
  • 将在所有(GETPOSTPUTDELETEHTTP请求上调用has_permission方法。
  • has_object_permission方法将不会在HTTP POST请求时调用,因此我们需要限制has_permission方法。
zzlelutf

zzlelutf2#

基本上,第一段代码拒绝所有的请求,因为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

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

8xiog9wr

8xiog9wr3#

我认为这会有所帮助:

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
b4qexyjb

b4qexyjb4#

据我所知,您没有将自定义权限作为参数添加到类中。
这是你的密码:

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

但它应该是:

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

注意,自定义权限IsAuthenticatedAndOwner是类头中的一个参数。
PS:我希望这能有所帮助,我是DRF的初学者,但这是我刚刚学到的东西之一。

zf9nrax1

zf9nrax15#

has_permission()是BasePermission类上的一个方法,用于检查用户是否有权对整个模型执行某个操作。例如,您可以使用它来检查用户是否有权查看某个模型的所有对象的列表。
has_object_permission()是BasePermission类上的一个方法,用于检查用户是否有权对模型的特定示例执行特定操作。例如,您可以使用它检查用户是否有权查看、更新或删除特定模型的特定对象。
例如,您的应用程序中可能有一个Book模型和一个User模型,您可以使用has_permission()检查用户是否有权查看所有书籍的列表,而使用has_object_permission()检查用户是否有权查看、更新或删除特定书籍。

class IsBookOwnerOrAdmin(permissions.BasePermission):
    def has_permission(self, request, view):
       # Check if the user is authenticated
       if not request.user.is_authenticated:
          return False
       # Allow access for superusers
       if request.user.is_superuser:
           return True
       # Allow access if the user is the owner of the book
       if request.method in permissions.SAFE_METHODS:
           return True
       return False

   def has_object_permission(self, request, view, obj):
       # Allow access for superusers
       if request.user.is_superuser:
           return True
       # Allow access if the user is the owner of the book
       return obj.owner == request.user

相关问题