我在Django的REST框架中有一个ModelViewSet
,它让我能够通过以下地址进行POST和GET:
api/v1/users
这些用户与评论表具有相反的关系,我希望能够通过URL访问这些评论:
api/v1/users/<username>/comments
我可以通过覆盖@detail_route
和queryset
设置自定义serializer_class
来实现此目的,但它仅适用于GET请求。如果我尝试通过REST Framework的管理部分发布新评论,我会收到一条错误通知,指出“'ListSerializer'对象不可迭代”
这是我的代码:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserFlat
lookup_field = 'username'
@detail_route(methods=['post','get'])
def comment(self, request, **kwargs):
user = self.get_object()
self.queryset = Comment.objects.filter(recipient=user.id)
self.serializer_class = CommentFlat
serializer = CommentFlat(instance=self.queryset, many=True)
return Response(serializer.data)
新评论应采用以下参数:
comment.author,comment.message,comment.recipient
我可以在管理面板中输入所有这些字段,并尝试创建一个帖子请求,但它失败了。理想情况下,我只需填写comment.message和comment.author,而comment.recipient字段应使用user.id自动填充,该地址在网址api/v1/users/<username>/comments
有谁知道为什么我的帖子请求没有完成以及如何自动填充该字段?
答案 0 :(得分:14)
我明白了。对于那些寻找答案的人来说,解决方案是明确定义request.method == 'POST'
时发生的操作并将对象传递给序列化器。
@detail_route(methods=['post','get'])
def comment(self, request, **kwargs):
user = self.get_object()
self.queryset = Comment.objects.filter(recipient=user.id)
self.serializer_class = CommentFlat
if request.method == 'POST':
# request.data is from the POST object. We want to take these
# values and supplement it with the user.id that's defined
# in our URL parameter
data = {
'comment': request.data['comment'],
'rating': request.data['rating'],
'author': request.data['author'],
'recipient': user.id
}
serializer = CommentFlat(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# Return GET by default
else:
serializer = CommentFlat(instance=self.queryset, many=True)
return Response(serializer.data)