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