RoofBite
RoofBite

Reputation: 11

Django Rest Framework get_permissions require one permission or other

I have defined get_permissions method on ListCreateAPIView and applied custom permissions there but I have one problem.

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()]

When I defined it like this Principal can only use POST method. But I also want that user to be able to use other methods. I have tried something like this :

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

But as I understand it requires all permission in list to be satisfied.

I am looking for something like this

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

I know that this possibility exists in permission_classes by writing

permission_classes = [IsAuthenticated | TeacherPermission]

Is there a simple way to do this or I am forced to write another custom permission that is granting permission if user is Teacher or Principal?

Upvotes: 1

Views: 1204

Answers (1)

Alexandr Tatarinov
Alexandr Tatarinov

Reputation: 4044

As in the example you have provided, | should be applied to the classes, so:

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

However, there is a way to simplify this, using the fact the @property and simple attributes are indistinguishable from the outside. I would recommend this pattern as a replacement for the overriding the get_permissions method.

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]

Upvotes: 4

Related Questions