'Is it possible to use complex logic in DRF ViewSet Permission Classes?

In the app I'm working on, I'd like it so that to create a task for a committee, you must be a member of the committee, the head of the committee, or an admin user, but you must also be authenticated. I understand this can be done with a few OR operators, but in the case that I need something more complex, I was hoping I could use nested lists of permission classes as such:

permission_classes = [
                         IsAuthenticated & 
                         [
                             IsCommitteeHead | 
                             IsCommitteeMember | 
                             IsAdminUser
                         ]
                     ]

Will this syntax work properly, or does rest_framework not understand this?



Solution 1:[1]

Yes, from the documentation:

class ExampleView(APIView):
    permission_classes = [IsAuthenticated|ReadOnly]

Note: it supports & (and), | (or) and ~ (not).

So in your case:

permission_classes = [IsAuthenticated &(IsCommitteeHead|IsCommitteeMember|IsAdminUser)]

Edit:

If using this notation inside get_permissions, you need to return class instances instead of classes. Note that entire expression should be one instance:

def get_permissions(self):
    return (
        IsAuthenticated & (IsCommitteeHead|IsCommitteeMember|IsAdminUser)
    )()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1