使用 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 的权限,这允许他们查看其中的所有 Block用户还可以将 Comment 添加到他们可以与其他用户共享的任何块。我使用 django-guardian 来管理基于对象的权限。

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

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() 的 QuerySet。然而,我不知道在哪里做这个。

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

解决方法

我对 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