在Django Rest Framework中添加特定方法处理器detail_route

3 投票
1 回答
4089 浏览
提问于 2025-05-10 21:08

我有一个用Django Rest Framework搭建的API。在里面有一个叫做ViewSet的部分,我想处理一些嵌套的数据:

from rest_framework.mixins import (RetrieveModelMixin, CreateModelMixin, 
                                   ListModelMixin)
from rest_framework.viewsets import GenericViewSet

class UserViewSet(RetrieveModelMixin, CreateModelMixin, ListModelMixin, 
                  GenericViewSet)

    ...

    @detail_route(methods=['get'], url_path='photos')
    def photos(self, request):
        return Response(self.get_photos())

    @detail_route(methods=['post'], url_path='photos')
    def new_photo(self, request, pk=None):
        a_new_photo = Photo(user=self.request.user)
        serializer = PhotoSerializer(data=request.data,
                                     instance=new_photo)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data,
                            status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我的目的是让这个ViewSet能够处理像这样的URL的GETPOST请求:

/api/users/42/photos

其中GET请求会返回用户ID为#42的照片列表,而POST请求则会为这个用户添加一张新照片。

但是,这个视图目前只处理一种方法:POST。对于GET请求,它返回了一个错误:

{"detail":"Method \\"GET\\" not allowed."}

我该如何用detail_route分别处理每种HTTP方法呢?

调试时输出这个视图的路由,并没有显示出明显的覆盖问题:

Route(url=u'^{prefix}/{lookup}/photos{trailing_slash}$', mapping={'post': 'new_photo'}, name=u'{basename}-photos', initkwargs={})
Route(url=u'^{prefix}/{lookup}/photos{trailing_slash}$', mapping={'get': 'photos'}, name=u'{basename}-photos', initkwargs={}) 

相关文章:

  • 暂无相关问题
暂无标签

1 个回答

5

一种选择是用一个加了detail_route的处理函数来同时处理GETPOST请求,然后在这个处理函数内部进行额外的分发。

@detail_route(methods=['get', 'post'])
def photos(self, request):
    if request.method == 'POST':
        return self.new_photo(request)

    return Response(self.get_photos())

撰写回答