用自定义的post方法和模型覆盖Django REST ViewSet [英] Overriding Django REST ViewSet with custom post method and model
问题描述
ModelViewSet
,使我能够通过以下地址进行POST和GET: api / v1 / users
这些用户与注释表有一个反向关系, 'd喜欢通过URL访问这些评论:
api / v1 / users /< username> / comments
我可以通过设置自定义 @detail_route
来覆盖 queryset
和 serializer_class
,但它只适用于GET请求。如果我尝试通过REST框架的管理部分发布新的注释,我收到一条错误通知,指出ListSerializer对象不可迭代
这是我的代码: / p>
class UserViewSet(viewsets.ModelViewSet):
/ pre>
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)
返回响应(serializer.data)
新评论应该采用以下参数:
comment.author,comment.message,comment 。收件人
我可以呃管理面板中的所有这些字段,并尝试创建一个发布请求,但它失败。理想情况下,我只需要填写comment.message和comment.author,并且comment.recipient字段应该自动填充在url
api / v1 / users /< username>>中获取的user.id ; / comments
有谁知道为什么我的发帖请求没有完成,以及我如何自动填充该字段?
解决方案我想出来了。对于那些寻求答案的人来说,解决方案是明确定义
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
如果request.method =='POST':
#request.data来自POST对象。我们想要使用这些
#值,并在我们的URL参数
data = {
'comment':request.data [']中定义了
#的user.id。评论'],
'rating':request.data ['rating'],
'author':request.data ['author'],
'recipient':user.id
}
serializer = CommentFlat(data = data)
如果serializer.is_valid():
serializer.save()
返回响应(serializer.data,status = status.HTTP_201_CREATED)
else:
返回响应(serializer.errors,status = status.HTTP_400_BAD_REQUEST)
#默认情况下返回GET
else:
serializer = CommentFlat(instance = self.queryset,many = True)
返回响应(serializer.data)
I have a a
ModelViewSet
in Django's REST Framework that gives me the ability to do a POST and GET through the following address:
api/v1/users
These Users have a a reverse relation to a Comments table and I'd like to be able to access these Comments through the URL:
api/v1/users/<username>/comments
I was able to do this by setting up a custom
@detail_route
by overriding thequeryset
and andserializer_class
but it only works for GET requests. If I attempt to POST a new comment through the REST Framework's admin section, I receive an error notice stating "'ListSerializer' object is not iterable"Here's my code:
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)
The new comment should take the following parameters:
comment.author, comment.message, comment.recipient
I can enter all those fields in the admin panel and attempt to create a post request but it fails. Ideally, I should only have to fill out comment.message and comment.author and the comment.recipient field should be autopopulated with user.id which is obtained in the url
api/v1/users/<username>/comments
Does anyone know why my post request isn't completing and how I can autofill that one field?
解决方案I figured it out. For those looking for an answer as well, the solution was to explicitly define the actions that occur when
request.method == 'POST'
and pass a the object into the serializer.@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)
这篇关于用自定义的post方法和模型覆盖Django REST ViewSet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!