2016-11-22 87 views
0

在我的REST API中,我有两个实体:TestTestRun。我希望能够发送POST请求以创建TestRun(以及相应的TestRun字段),但此请求的URL必须是api/v1/test/{id}/start而不是api/v1/testrun。 我知道,使用@detail_route我可以自定义URL,但随后的请求仍然被发送到api/v1/test/{id}发布到一个资源的URL以创建另一个不同的资源

class TestViewSet(viewsets.ModelViewSet): 
    queryset = Test.objects.all() 
    serializer_class = TestSerializer 

    @detail_route(methods=['post'], url_path='start') 
    def start_test(self, request, pk=None): 
     pass 

class TestRunViewSet(viewsets.ModelViewSet): 
    queryset = TestRun.objects.all() 
    serializer_class = TestRunSerializer 

也许在这里需要一些高度定制的路由器?

回答

1

好的,我有一个基本的例子。我觉得你有一些问题,所以首先第一件事情:

我的观点:

class TestViewSet(viewsets.ModelViewSet): 
    queryset = Test.objects.all() 
    serializer_class = TestSerializer 

    @detail_route(methods=['post'], url_path='start', serializer_class=TestRunSerializer) 
    def start_test(self, request, pk=None): 
     serializer = self.get_serializer(data=request.data) 
     if serializer.is_valid(): 
      # add here TestRun object 
      return Response(serializer.data, status=status.HTTP_200_OK) 


class TestRunViewSet(viewsets.ModelViewSet): 
    queryset = TestRun.objects.all() 
    serializer_class = TestRunSerializer 

我的网址:

router = SimpleRouter() 
router.register('test', TestViewSet) 
router.register('test-run', TestRunViewSet) 

urlpatterns = router.urls 

和设置网址:

urlpatterns = [ 
    url(r'^api/v1/', include('droute.urls')) 
] 

在这种情况下你对Test和TestRun模型有完整的CRUD - 一个在api/vi/test下,另一个在api/v1/test-run中;

的detail_route装饰为您创造更多的途径:/ API/V1 /测试/:ID /启动

但是,这并不意味着在API/V1 /试运行即CRUD不再访问。

如果您不想在api/v1/test-run上创建,您应该使用ReadOnlyModelViewSet作为TestRunViewSet的基础 - 这将只允许列表端点上的GET:api/v1/test-run并在详细信息端点上:api/v1/test-run //

您不需要在路由器上制造魔法 - 就像例子SimpleRouter就足够了。

如果你想制作嵌套路由器,事情会变得更复杂一点。你可以搜索stackoverflow - 有很多关于这方面的文章。但说实话我会阻止你使用嵌套的路由器,我从来不觉得这个工作是一种乐趣:)你可以点击这里: https://github.com/alanjds/drf-nested-routers

我认为(但我有很少或NONO信息),最好的你API会是这样的:

  • /API/V1 /测试 - > CRUD测试
  • /API/V1 /测试/:ID /开始 - >开始测试POST
  • /api/v1/test /:id/runs - >获取运行列表GET(在TestViewSet或嵌套路由器上的list_route)
  • /api/v1/test /:id/runs /:run_id - >获取运行细节GET(这里是一个问题 - 因为它意味着你需要嵌套:(或者附加到url的自定义视图)

快乐编码,希望这有助于。