代码之家  ›  专栏  ›  技术社区  ›  manabreak

如何让用户只获取与他们相关的对象(通过多对多关系)?

  •  0
  • manabreak  · 技术社区  · 7 年前

    我有一个项目,其中有工作区,每个工作区可以有任意数量的用户。用户也可以属于多个工作区,因此它们之间存在多对多关系。

    现在,我有了工作区创建和成员资格,但我在设置权限时遇到了问题,因此只有工作区成员才能看到工作区。我尝试过使用自定义对象级权限,但似乎不起作用。

    工作区模型如下所示:

    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()
    
    0 回复  |  直到 7 年前
        1
  •  1
  •   SourPatchAdult    7 年前

    我强烈推荐 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 附加到特定工作区的用户或组。

    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')
    
    推荐文章