Django REST:在1个网址上显示详细信息和列表

时间:2016-12-26 09:05:05

标签: python django django-rest-framework

有一个使用REST API的Django项目。

大多数网址模式遵循相同的范例:

/foo_config/1

基本上/list-view/details-view

但是还有另一种类型的配置 - 它只能有1个对象,因此显示它像/bar_config/1一样令人困惑,因为用户可能期望#2和#3等。

我想使用简单的bar_config'映射'/bar_config个详细信息和列表。

尝试使用@detail_route,但不起作用:

@detail_route(methods=['put'])
def put_config(self, request):
  ...

如何实现我的目标?

UPDATE:在尝试使用detail_route和Ivan Semochkin回答后 - 仍然没有运气。我将提供有关我所拥有的更多详细信息:

/accounts/foo_account/bar_config/< - 列表视图 /accounts/foo_account/bar_config/1< - 详情视图

帐户定义为:

router = routers.DefaultRouter()
router.register('accounts', AccountViewSet)

目标是:

  1. bar_config/1上显示bar_config(LIST页面上的PUT);
  2. 禁止/隐藏bar_config/1;
  3. 允许查看和更新​​信息,禁止创建/删除;
  4. 我将总结一下:我需要改变子链接在现有项目中的工作方式,该项目已经为其所有模式使用DefaultRouter。该子链接映射单例模型。我想在列表(GET)页面上显示更新(PUT)数据。

1 个答案:

答案 0 :(得分:5)

为什么不覆盖list方法?

class ConfigViewSet(viewsets.ReadOnlyModelViewSet):

    queryset = Config.objects.all()  
    serializer_class = ConfigSerializer

    def retrieve(self, request, *args, **kwargs):
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

    def list(self, request, *args, **kwargs):
        instance = self.get_queryset().first()
        # using 'first' will retrieve first instance
        serializer = self.get_serializer(instance)
        return Responce(serializer.data)

它不会很好,你不会只显示该模型。如果您想提供一些CRUD,请继承ModelViewSet并覆盖deleteupdate方法。
评论更新
另一种方法 - 创建自定义路由器,使用此路由器,您不需要使用list,而是使用检索

from rest_framework.routers import Route, SimpleRouter

class CustomRouter(SimpleRouter):
"""
A router for update and retrieve without lookup field.
"""
    routes = [
       Route(
            url=r'^{prefix}/$',
            mapping={'put': 'update'},
            name='{basename}-update',
            initkwargs={'suffix': 'Update'}
        ),
        Route(
            url=r'^{prefix}/$',
            mapping={'get': 'retrieve'},
            name='{basename}-detail',
            initkwargs={'suffix': 'Detail'}
        ),
    ]  

ViewSet:

class ConfigViewSet(viewsets.ModelViewSet):

    queryset = Config.objects.all()  
    serializer_class = ConfigSerializer

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_queryset().first()
        # using 'first' will retrieve first instance
        serializer = self.get_serializer(instance)
        return Responce(serializer.data)

    def update(self, request, *args, **kwargs):
        instance = self.get_queryset().first()
        serializer = self.get_serializer(instance, data=request.data)
        # you could also provide `partial=True` in serializer for partial update
        if serializer.is_valid():
            serializer.save() 
            return Responce(serializer.data)
        else:
            return Responce(serializer.errors)

网址:

router = CustomRouter()
router.register('config', ConfigViewSet)
urlpatterns = router.urls