Django Rest Framework get_permissions 需要一个或其他权限

Posted

技术标签:

【中文标题】Django Rest Framework get_permissions 需要一个或其他权限【英文标题】:Django Rest Framework get_permissions require one permission or other 【发布时间】:2021-10-07 02:59:57 【问题描述】:

我在 ListCreateAPIView 上定义了 get_permissions 方法并在那里应用了自定义权限,但我遇到了一个问题。

class ListSchoolStudents(generics.ListCreateAPIView, TeacherPermission):
    serializer_class = StudentSerializerForList
    permission_classes = [IsAuthenticated & TeacherPermission]
    
    def get_queryset(self):
        pk = self.kwargs['pk']
        
        return Student.objects.filter(school__id = pk).select_related('school','school_class').prefetch_related('subject')

    def get_permissions(self):
        if self.request.method in ['POST']:
            
            return [PrincipalPermission()]
        
        return [permissions.IsAuthenticated(), TeacherPermission()]

当我像这样定义它时,Principal 只能使用 POST 方法。但我也希望该用户能够使用其他方法。我尝试过这样的事情:

def get_permissions(self):
        if self.request.method in ['POST']:
            return [PrincipalPermission()]
        return [permissions.IsAuthenticated(), TeacherPermission(), PrincipalPermission() ]

但据我了解,它需要满足列表中的所有权限。

我正在寻找这样的东西

return [permissions.IsAuthenticated(), TeacherPermission() or PrincipalPermission() ]

我知道这种可能性存在于permission_classes中

permission_classes = [IsAuthenticated | TeacherPermission]

是否有一种简单的方法可以做到这一点,或者如果用户是教师或校长,我不得不编写另一个自定义权限来授予权限?

【问题讨论】:

【参考方案1】:

在您提供的示例中,| 应该应用于类,因此:

return [permissions.IsAuthenticated(), (TeacherPermission | PrincipalPermission)() ]

但是,有一种方法可以简化这一点,利用 @property 和简单属性与外部无法区分的事实。我会推荐这种模式来替代覆盖 get_permissions 方法。

class ListSchoolStudents(generics.ListCreateAPIView, TeacherPermission):
    serializer_class = StudentSerializerForList

    @property
    def permission_classes(self):
        if self.request.method in ['POST']:
            return [PrincipalPermission]
        return [IsAuthenticated, TeacherPermission | PrincipalPermission]

【讨论】:

感谢这是一个很好的解决方案,我同时创建了自己的解决方案,但你的要好得多。

以上是关于Django Rest Framework get_permissions 需要一个或其他权限的主要内容,如果未能解决你的问题,请参考以下文章

Getting Started with Django Rest Framework and AngularJS

Django Rest Framework Api 查看 GET

18-Django REST framework-使用Django开发REST 接口

如何自定义 Django REST Framework GET 请求的响应?

Django REST Framework Viewset 返回 404(GET 请求)

Django REST framework框架之GET, POST, PUT, PATCH, DELETE等API请求接口设计