在Django Rest Framework中添加特定的方法处理程序detail_route

时间:2015-11-23 00:45:52

标签: python django django-rest-framework

我有一个使用Django Rest Framework构建的API。其中有一个ViewSet detail_route我试图处理嵌套数据:

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同时处理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 个答案:

答案 0 :(得分:5)

一个选项是使用一个GET处理的处理程序处理POSTdetail_route,并在处理程序中执行其他调度:

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

    return Response(self.get_photos())