首页 > 解决方案 > 使用 Guardian 检查序列化子对象的权限

问题描述

我有三个模型,其中一个文档有很多块,一个块有很多评论。

class Document(models.Model):
  name = models.Charfield()

class Block(models.Model):
  document = models.ForeignKey(to=Document)

class Comment
  block = models.ForgeinKey(to=Block)

用户可以拥有Document允许他们查看其中所有Blocks 的权限。用户还可以将Comments 添加到其他用户可以共享的任何块中。我使用django-guardian来管理基于对象的权限。

我创建了一个RetrieveAPIView使用 Django Rest Framework 来使文档可用。

class DocumentDetailView(PermissionRequiredMixin, RetrieveAPIView):
    serializer_class = DocumentSerializer
    permission_required = "document.view_document"

为了在该视图中包含所有块及其注释,我使用以下序列化程序(class Meta为简洁起见省略):

class DocumentSerializer(serializers.ModelSerializer):
    blocks = BlockSerializer(many=True, source="block_set")

class BlockSerializer(serializers.ModelSerializer):
    comments = serializers.CommentSerializer(many=True, source="comment_set")

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment

我想将包含的评论限制DocumentDetailView为用户有权访问的评论。按照 django-guardian 的逻辑,我将使用get_objects_for_users(), 来过滤Block.comment_set.all(). 然而,我不知道在哪里做这个。

我想将评论限制为可用于的评论request.user,基于权限的过滤应该在 中完成DocumentDetailView,但我不知道如何在get_object().

标签: djangodjango-rest-frameworkdjango-guardian

解决方案


我不太了解,django-guardian但我想您可以覆盖该get_queryset方法:

class DocumentDetailView(PermissionRequiredMixin, RetrieveAPIView):
    serializer_class = DocumentSerializer
    permission_required = "document.view_document"

    def get_queryset(self):
        if self.check_permissions():
            queryset = super().get_queryset()
            return queryset.filter(...)  # <- here you permission filter

推荐阅读