has_object_permission 和 has_permission 有什么区别?
What's the differences between has_object_permission and has_permission?
我对 Django-rest-framework 中的BasePermission
感到困惑。
这里我定义了一个class: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
。
我曾经这样定义class: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
有什么区别?
基本上,第一个代码否定了一切,因为 has_permission
return 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
这也将允许经过身份验证的用户创建新项目或列出它们。
我们在BasePermission
class上有以下两种权限方式:
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_permission
方法在 has_permission
方法之后被调用 returns 值 True
除了在 POST 方法中(仅在 POST
方法中 has_permission
被执行)。
- 当
permission_classes
方法返回False
值时,请求没有权限,不会再循环,否则,它会在循环时检查所有权限。
has_permission
方法将在所有 (GET
, POST
, PUT
, DELETE
) HTTP
请求上调用。
has_object_permission
方法不会在 HTTP POST
请求中被调用,因此我们需要从 has_permission
方法中限制它。
我认为这可以帮助:
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
我对 Django-rest-framework 中的BasePermission
感到困惑。
这里我定义了一个class: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
。
我曾经这样定义class: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
有什么区别?
基本上,第一个代码否定了一切,因为 has_permission
return 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
这也将允许经过身份验证的用户创建新项目或列出它们。
我们在BasePermission
class上有以下两种权限方式:
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_permission
方法在has_permission
方法之后被调用 returns 值True
除了在 POST 方法中(仅在POST
方法中has_permission
被执行)。- 当
permission_classes
方法返回False
值时,请求没有权限,不会再循环,否则,它会在循环时检查所有权限。 has_permission
方法将在所有 (GET
,POST
,PUT
,DELETE
)HTTP
请求上调用。has_object_permission
方法不会在HTTP POST
请求中被调用,因此我们需要从has_permission
方法中限制它。
我认为这可以帮助:
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