Как позволить пользователю выбирать только те объекты, с которыми он связан (по соотношению многие ко многим)? - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть проект, в котором есть рабочие пространства, и каждая рабочая область может иметь любое количество пользователей.Пользователи также могут принадлежать к нескольким рабочим областям, поэтому между ними существует отношение многие ко многим.

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

Модель рабочей области выглядит следующим образом:

class Workspace(models.Model):
    name = models.CharField(max_length=100)
    users = models.ManyToManyField(User, related_name='workspaces')

Вид выглядит следующим образом:

class WorkspaceViewSet(viewsets.ModelViewSet):
    queryset = Workspace.objects.all().order_by('name')
    serializer_class = WorkspaceSerializer
    permission_classes = [permissions.IsAuthenticated|BelongsInWorkspace]

Сериализатор выглядит так:

class WorkspaceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Workspace
        fields = ('name', 'users')

    def create(self, validated_data):
        instance = super(WorkspaceSerializer, self)
        instance.users.add(self.context['request'].user)
        return instance

И, наконец, пользовательское разрешение, которое я пытаюсь использовать здесь:

class BelongsInWorkspace(BasePermission):
    def has_permission(self, request, view):
        return True

    def has_object_permission(self, request, view, obj):
        return obj.users.filter(pk=request.user).exists()

1 Ответ

0 голосов
/ 24 сентября 2019

Я бы настоятельно рекомендовал django-guardian для решения этой проблемы.Django-guardian обеспечивает прямое управление разрешениями на уровне объектов.

Чтобы решить вашу проблему, все, что вам нужно сделать, это добавить класс Meta в модель рабочей области, где вы можете создавать собственные разрешения.

 class Workspace(models.Model):
    name = models.CharField(max_length=100)
    users = models.ManyToManyField(User, related_name='workspaces')

    class Meta:
        default_permissions = ('add', 'change', 'delete')
        permissions = (
                ('access_workspace', 'Access workspace'),
                )

Назначьте пользователя или группу с таким разрешением, прикрепленных к определенной рабочей области.

assign_perm('access_workspace', user, workspace)

#This will return True if the user has been properly assigned the permission
user.has_perm('access_workspace', workspace)

Затем, чтобы получить все рабочие области, к которым у пользователя есть доступ,вам просто нужно вызвать get_objects_for_user () по вашему мнению

queryset = get_objects_for_user(self.request.user, 'project.access_workspace')
...