【问题标题】:What's the differences between has_object_permission and has_permission?has_object_permission 和 has_permission 有什么区别?
【发布时间】:2017-08-21 05:22:15
【问题描述】:

我对 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有什么区别呢?

【问题讨论】:

    标签: django django-rest-framework django-rest-framework-permissions


    【解决方案1】:

    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_object_permission方法在has_permission方法返回值True之后被调用,除了在POST方法中(在POST方法中只执行has_permission)。
    • permission_classes方法返回False值时,请求没有权限,不会再循环,否则,循环时检查所有权限。
    • 将在所有(GETPOSTPUTDELETEHTTP 请求上调用 has_permission 方法。
    • has_object_permission 方法不会在 HTTP POST 请求中被调用,因此我们需要将其限制在 has_permission 方法中。

    【讨论】:

    【解决方案2】:

    基本上,第一个代码否认一切,因为 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
    

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

    【讨论】:

    • 谢谢你的回答。可能我的问题不是很清楚。起初我的代码和你的一样。但是它不起作用,每个人都可以通过权限。然后我通过@更新函数987654326@。它仍然通过每个人。
    • 那么有什么区别呢?为什么我们需要 2 个函数而不是一个函数?
    • DRF 文档对此进行了解释。 has_permission 是一个“通用”权限检查,用于查看请求是否符合某些标准。 has_object_permission 更具体,并链接到特定实例。
    【解决方案3】:

    我认为这会有所帮助:

    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
    

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 1970-01-01
      • 2010-10-02
      • 2011-12-12
      • 2010-09-16
      • 2012-03-14
      • 2012-02-06
      • 2011-02-25
      • 2011-11-22
      相关资源
      最近更新 更多