我希望用户只能访问属于他们的记录,而不能访问任何其他用户的记录,所以
我创建了以下 view
:
class AddressViewSet(viewsets.ModelViewSet):
authentication_classes = (TokenAuthentication,)
permission_classes = [IsAuthenticated, IsOwner]
queryset = Address.objects.all()
def retrieve(self, request, pk):
address = self.address_service.get_by_id(pk)
serializer = AddressSerializer(address)
return Response(serializer.data, status=status.HTTP_200_OK)
我只希望记录的所有者能够访问此 View 中的所有方法,即检索、列表等(稍后我将实现剩余的方法)所以我创建了以下 permissions.py
文件在我的core
应用:
class IsOwner(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
print('here in has_object_permission...')
return obj.user == request.user
这行不通,所以在查看了 stackoverflow 的答案后,我找到了这个 Django Rest Framework owner permissions它表示 has_permission
必须实现方法。但是正如您在该答案中看到的那样,它正在尝试获取 id
来自 view.kwargs
但是我的view.kwargs
仅包含 pk
而不是用户。我怎样才能解决这个问题?我是否需要在请求 url 中隐式传递用户 ID?这听起来不对。
这是我用来验证用户无法访问其他用户记录的测试:
def test_when_a_user_tries_to_access_another_users_address_then_an_error_is_returned(self):
user2 = UserFactory.create()
addresses = AddressFactory.create_batch(3, user=user2)
address_ids = [address.id for address in addresses]
random_address_id = random.choice(address_ids)
url = reverse(self.ADDRESSES_DETAIL_URL, args=(random_address_id,))
res = self.client.get(url, format='json')
print(res.data)
目前只是使用测试来检查返回的数据,稍后会实现断言。
编辑
所以我添加了has_permission
IsOwner
的方法:
def has_permission(self, request, view):
return request.user and request.user.is_authenticated
如果我在此处放置打印语句,它会被打印出来,但似乎没有达到 has_object_permission
方法,我添加的打印件都没有显示
最佳答案
This answer对我来说是正确的。
它说:
The has_object_permission is not called for list views. The documentation says the following:
Also note that the generic views will only check the object-level permissions for views that retrieve a single model instance. If you require object-level filtering of list views, you'll need to filter the queryset separately. See the filtering documentation for more details.
关于Django Rest Framework 自定义权限不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66739195/