在Django rest框架中组合2个自定义权限

2024-06-16 08:51:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个名为Showcase的模型,用户使用它来展示项目,还有一个协作模型,用户可以在其中向展示中添加协作者。我正在尝试实现一个案例,其中showcase中的管理员和协作中的用户可以删除该协作

为了更好地解释,在showcase模型中,有一个管理showcase的管理员列表。他们还可以(通过Collaborator模型)向showcase添加协作者。Collaborator有一个用户字段,该字段是为showcase贡献的用户

我希望在添加协作者后,该用户可以删除自己(如果他不想成为showcase的一部分),或者管理员可以删除该协作者(如果他添加了一个错误的用户并想从showcase中删除他)

models.py

class Showcase(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField(null=True)
    skill_type = models.ForeignKey(Skill, on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="Showcases")
    content = models.TextField(null=True)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    voters = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="upvotes")
    slug = models.SlugField(max_length=255, unique=True)
    administrator = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="administrators", blank=True)


class Collaborator(models.Model):
    post = models.ForeignKey(Showcase, on_delete=models.CASCADE, related_name="collaborated_showcases")
    user = models.ForeignKey(settings.AUTH_USER_MODEL, 
                            on_delete=models.CASCADE, related_name="collaborators")
    skill = models.ForeignKey(Skill, on_delete=models.CASCADE, null=True, related_name="creative_type")
    role = models.TextField(null=True)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)

权限.py

class IsUser(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return False
        return obj.user == request.user


class IsAdmin(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return False
        return request.user.administrators.filter(pk=obj.pk).exists()

view.py

class CollaboratorDeleteView(APIView):
    '''
    Allow Administrators to delete a collaborator to a showcase 
    or allow the collaborator user to be able to delete himself 
    '''
    permission_classes = [IsAdmin]

    def delete(self, request, pk):
        collaborator = get_object_or_404(Collaborator, pk=pk)
        showcase = collaborator.post

        try:
            self.check_object_permissions(request, showcase)
            collaborator.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        except APIException:
            return Response(status=status.HTTP_403_FORBIDDEN)

网址

path("collaborator/<int:pk>/delete/", qv.CollaboratorDeleteView.as_view(), name="collaborator-delete-view"),

现在我已经能够实现管理员可以删除协作者,但是如何在Collaborator模型中为用户添加另一个权限,以便能够通过该视图删除自己作为协作者


Tags: 用户name模型truereturnonmodelsrequest
2条回答

您可以使用&;根据需要向permission_classses属性添加任意多的权限;(和),(或)和(非)符号(doc):

class CollaboratorDeleteView(APIView):
    '''
    Allow Administrators to delete a collaborator to a showcase 
    or allow the collaborator user to be able to delete himself 
    '''
    permission_classes = [IsAdmin|IsUser]

这两个权限现在都可以使用OR逻辑

实际上,这两个权限可以合并为一个。例如,按如下方式更新权限:

class CanDeleteUser(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return False
        return obj.user == request.user or ob.post.administrator.filter(pk=request.user.pk).exists()

在这里,我检查request.userobj.user还是检查带有obj变量的showcase对象的管理员

现在我只想检查collaborator的权限

class CollaboratorDeleteView(APIView):
    '''
    Allow Administrators to delete a collaborator to a showcase 
    or allow the collaborator user to be able to delete himself 
    '''
    permission_classes = [CanDeleteUser]

    def delete(self, request, pk):
        collaborator = get_object_or_404(Collaborator, pk=pk)

        try:
            self.check_object_permissions(request, collaborator)

相关问题 更多 >