Django休息:在1个URL上显示详细信息和列表



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

大多数URL模式遵循相同的范式:

/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):
  ...

如何实现我的目标?

更新:尝试使用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上显示bar_config/1(放在列表页面上);
  2. 禁止/隐藏bar_config/1;
  3. 允许查看和更新信息,禁止创建/删除;

我将总结:我需要更改子链接在现有项目中的工作方式,该项目已经使用DefaultRouter用于其所有模式。这个子链接地图单元模型。我想在列表(GET)页面上显示更新(put)数据。

为什么不覆盖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 Response(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'}
        ),
    ]  

视图集:

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 Response(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 Response(serializer.data)
        else:
            return Response(serializer.errors)

url:

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

最新更新