对象权限函数多次触发

时间:2019-06-24 08:34:05

标签: python django django-rest-framework

我正在使用Django Rest Framework。我想给RetrieveUpdateDestroyAPI View权限类

我的权限等级:

class AssetItemPermission(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        user = request.user
        shared_item_course = False

        is_content_author = PermissionHelper().check_permission(
            request.user, ['create_content'])

        courses = Course.objects.filter(module=obj)

        if any(obj.tenant in course.tenants.all() for course in courses):
            shared_item_course = True
        elif any(obj.status==TenantShareItemStatusValues.SHARED_TO_ALL.value for course in courses):
            shared_item_course = True

        if Enrolment.objects.filter(enrollable__in=courses, enrollee=request.user, 
                                    status=EnrolmentStatus(short_name=EnrolmentStatusValues.APPROVED.value)
                                   ).exists():
            print("Is enrolled by user")
            return True
        elif is_content_author and obj.tenant == request.user.tenant:
            print("is content author and it is in tenant")
            return True
        elif is_content_author and shared_item_course:
            print("is content author and it is in tenant share item")
            return True

        return False

我的观点:

class AssetItemView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = AssetItemsSerializer
    permission_classes = [AssetItemPermission]

    def get_queryset(self):
        return Module.objects.filter(id=self.kwargs['pk'])

它可以工作,但是我发现权限检查被触发了5次:

例如,打印语句“是内容作者并且在租户中”打印5次而不是1次。为什么会发射5次?

1 个答案:

答案 0 :(得分:2)

第一个权限检查是查看用户是否能够访问所请求的资源。之后,BrowsableAPIRenderer将运行所有这些权限检查,以查看用户是否有权访问HTTP方法PUTPATCH DELETE和{{1} },以确定所呈现的模板是否应包含允许您对请求的资源执行这些操作的按钮。最初的权限检查是您是否具有OPTIONS权限。当我在本地运行此命令时,实际上我会看到6次检查,因为我不确定两次对PUT进行两次检查。

如果您在GET中添加print(request.method)行,就可以看到这一点。

如果您在网址末尾添加has_object_permission,或者如果在查询字符串中添加?format=json(如果在其中还有其他参数),则将强制使用format=json,只会获取并返回数据,而没有可浏览的API模板。因此,无需进行额外的权限检查即可查看渲染器是否应在模板上创建这些按钮。 JSONRenderer将仅对JSONRenderer请求执行一次权限检查。