Django休息框架自定义POST权限

时间:2015-09-20 13:30:58

标签: django post permissions django-rest-framework

使用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都不太熟悉,但我很困惑,因为我所说的是一种自定义权限(权限在视图中处理,对吧?)。

寻找良好实践提示:)

1 个答案:

答案 0 :(得分:4)

创建

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

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

然后在您PostViewSet的{​​{1}},代替

create

def perform_create(self, serializer): serializer.save(author=self.request.user) 是一个在数据验证后从perform_create调用的钩子,因此您不必费心去做并自己创建create

更新&删除

但是,当您进行更新或删除时,可以添加Response之类的自定义权限类来验证IsAuthorOrReadOnly。您可以从完全符合您需求的second example here (IsOwnerOrReadOnly class)中激励自己。

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

post.author == request.user