Структура Django REST: проверка пользователя в группе

Мне было интересно, как создать пользовательское разрешение, которое проверяет, находится ли пользователь в определенной группе. Раньше у меня был декоратор, который я мог использовать для представления в кортеже имен групп вместе с пользовательским объектом, а затем проверить, был ли этот пользователь в указанных группах.

Т.е:

def in_group_views(*group_names):
    """Requires user membership in at least one of the groups passed in."""

    def in_groups(u):
        if u.is_authenticated():
            if bool(u.groups.filter(name__in=group_names)) | u.is_superuser:
                return True
        return False

    return user_passes_test(in_groups)

Как мне сделать это для DRF для просмотра, учитывая, что мне нужно проверить разные членства в группах для разных действий (POST, PUT, GET) и т.д.

Большое спасибо, Бен

Ответы

Ответ 1

Разумным способом параметризации классов разрешений является включение параметров в класс представления. Это позволит вам изменить поведение в представлении для просмотра.

Вот пример:

def is_in_group(user, group_name):
    """
    Takes a user and a group name, and returns `True` if the user is in that group.
    """
    return Group.objects.get(name=group_name).user_set.filter(id=user.id).exists()

class HasGroupPermission(permissions.BasePermission):
    """
    Ensure user is in required groups.
    """

    def has_permission(self, request, view):
        # Get a mapping of methods -> required group.
        required_groups_mapping = getattr(view, 'required_groups', {})

        # Determine the required groups for this particular request method.
        required_groups = required_groups_mapping.get(request.method, [])

        # Return True if the user has all the required groups.
        return all([is_in_group(request.user, group_name) for group_name in required_groups])

Затем вы можете использовать класс HasGroupPermission следующим образом:

class MyView(APIView):
     permission_classes = [HasGroupPermission]
     required_groups = {
         'GET': ['moderators', 'members'],
         'POST': ['moderators'],
     }

     ...

Надеюсь, что это поможет!