我正在实现一个有嵌套结构的 API。
假设它是一个动物园,我可以调用GET /api/cage/
获取笼子列表GET /api/cage/1/
以获取笼子 ID 1,但随后我可以GET /api/cage/1/animals/
获取该笼子中的动物列表。
我遇到的问题是权限。如果我能看到笼子本身,我应该只能看到笼子里的动物。如果在相关权限类中has_object_permission()
返回,我应该能够看到笼子本身。True
出于某种原因,has_object_permission()
当我做 GET 时被调用/api/cage/1/
,但has_permission()
在我调用时被调用GET /api/cage/1/animals/
。而且has_permission()
我无权访问该对象来检查权限。我错过了什么吗?我该怎么做呢?
我的笼子视图或多或少看起来像这样
class CageViewSet(ModelViewSet):
queryset = Cage.objects.all()
serializer_class = CageSerializer
permission_classes = [GeneralZooPermissions, ]
authentication_classes = [ZooTicketCheck, ]
def get_queryset(self):
... code to only list cages you have permission to see ...
@detail_route(methods=['GET'])
def animals(self, request, pk=None):
return Request(AnimalSerializer(Animal.objects.filter(cage_id=pk), many=True).data)
我的GeneralZooPermissions
课看起来像这样(目前)
class GeneralZooPermissions(BasePermission):
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj):
return request.user.has_perm('view_cage', obj)
这似乎是 DRF 中的一个错误。详细路由不调用正确的权限检查。我曾尝试向 DRF 开发人员报告此问题,但我的报告似乎消失了。不知道下一步该怎么做。想法?
我用 DRF 发布的问题又回来了,我得到了回复。似乎只检查has_permission()
而不是has_object_permission()
预期的行为。这对我没有帮助。此时,必须执行以下操作:
class CustomPermission(BasePermission):
def has_permission(self, request, view):
"""we need to do all permission checking here, since has_object_permission() is not guaranteed to be called"""
if 'pk' in view.kwargs and view.kwargs['pk']:
obj = view.get_queryset()[0]
# check object permissions here
else:
# check model permissions here
def has_object_permission(self, request, view, obj):
""" nothing to do here, we already checked everything """
return True