【问题标题】:Django rest framework custom POST permissionsDjango rest 框架自定义 POST 权限
【发布时间】:2015-09-20 13:30:58
【问题描述】:

使用 DRF 设置用户可以共享内容的平台,我无法检查作者是否与登录的用户匹配。

内容模型示例:

    class Post(models.Model):
        date = models.DateTimeField()
        author = models.ForeignKey(User)
        content = models.CharField(max_length=512)

内容序列化器:

    class PostSerializer(serializers.ModelSerializer):
        class Meta:
            model = Post

内容视图:

    @authentication_classes((SessionAuthentication, BasicAuthentication,))
    @permission_classes((IsAuthenticated,))
    class PostViewSet(viewsets.ModelViewSet):
        queryset = Post.objects.all()
        serializer_class = PostSerializer
        http_method_names = ['get', 'post', 'head', 'options',]

我希望帖子请求在保存帖子之前执行 post.author == request.user 测试。

一方面我的直觉告诉我应该用那种代码覆盖视图的 create 方法(未经测试,但在这里我只是想说明我想要做什么):

    class PostViewSet(viewsets.ModelViewSet):
        [...]
        def create(self, request):
            post = self.get_object()
            serializer = PostSerializer(data=request.data)
            if serializer.is_valid():
                if serializer.validated_data.author == request.user:
                    serializer.save()
                    return Response({'message': 'Post saved !'})
                else:
                    return Response({'message': 'You can't post for someone else'})
            else:
                return Response({'message': 'Not valid...'})

另一方面,当我在我最喜欢的搜索引擎上搜索类似问题时,我只能找到涉及覆盖序列化程序类中的创建/更新方法的答案。

我对rest apis和DRF不太熟悉,但我很困惑,因为我说的是一种自定义权限(权限是在视图中处理的,对吧?)。

寻找好的做法提示:)

【问题讨论】:

  • 请将您的答案中的“post”更改为POST,您的意思是HTTP方法。

标签: django post permissions django-rest-framework


【解决方案1】:

创建

author 字段留给用户编辑然后验证其值没有多大意义,您可以在create 中为用户设置它。所以在你的序列化器中它会是:

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        read_only_fields = ('author',)

然后在PostViewSet代替你的create

def perform_create(self, serializer):
    serializer.save(author=self.request.user)

perform_create 是一个钩子,在数据验证后从create 调用,因此您不必费心自己创建Response

更新和删除

不过,当您进行更新或删除时,您可以添加一个自定义权限类,例如 IsAuthorOrReadOnly,它会验证 post.author == request.user。您可以从完全符合您需求的second example here (IsOwnerOrReadOnly class) 中获得灵感。

然后您可以将其用作任何其他权限类,例如:

@permission_classes((IsAuthenticated, IsAuthorOrReadOnly, ))
class PostViewSet(viewsets.ModelViewSet):
    # ...

【讨论】:

    猜你喜欢
    • 2020-09-22
    • 1970-01-01
    • 2016-01-10
    • 2018-07-03
    • 1970-01-01
    • 2017-04-13
    • 2016-11-20
    • 2016-05-03
    • 2018-08-18
    相关资源
    最近更新 更多