Skip to main content
 首页 » 编程设计

python之Django Rest Framework 中 CreateAPIView 的权限

2025年05月04日36cmt

我查看了 CreateAPIView 的代码,在创建过程中没有检查权限。所以我决定在 perform_create 钩子(Hook)中检查它们,如下所示:

class CourseList(generics.CreateAPIView): 
    """ 
    Create a course. 
    A user can create a course if he/she is an instructor in 
    the academy the course is to be created in. 
    """ 
    serializer_class = CourseRef 
    queryset = Course.objects.all() 
    permission_classes = (IsAuthenticated, IsInstructorInAcademy) 
 
    def perform_create(self, serializer): 
        self.check_object_permissions(self.request, serializer.validated_data.get('academy')) 
        serializer.save() 

权限看起来像:

class IsInstructorInAcademy(BasePermission): 
    def has_object_permission(self, request, view, academy): 
        return request.user.instructor_set.filter(academy=academy).exists() 

当我尝试创建类(class)时,初始权限检查运行正常并且类(class)已保存,但之后我立即收到以下错误:

ValueError at /api/courses/ 
Cannot query "Mathematics 11A": Must be "Academy" instance. 

这是在权限检查时引发的,结果是 POST 返回 500 ISE。

(这有点老套,因为我在 perform_create Hook 的权限检查中传入了学院实例,而 View 确实与类(class)有关。我考虑过使用权限 IsInstructorInAcademyOfObject 但为此,我需要传入一个对象,除非保存序列化程序,否则我无法获取该对象。)

在这里检查权限的最佳方法是什么?

请您参考如下方法:

您遇到问题是因为您将业务逻辑检查与权限绑定(bind)。

不要调用 check_object_permission,而是在反序列化后执行您自己的检查,如果失败则引发 PermissionDenied。