0le*_*leg 2 python django django-rest-framework
有一个使用REST API的Django项目.
大多数url模式遵循相同的范例:
/foo_config/1
Run Code Online (Sandbox Code Playgroud)
基本上 /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):
...
Run Code Online (Sandbox Code Playgroud)
如何实现我的目标?
更新:尝试detail_route与Ivan Semochkin 一起玩后回答 - 仍然没有运气.我会提供更多有关我所拥有的细节:
/accounts/foo_account/bar_config/< - list view
/accounts/foo_account/bar_config/1< - 详细信息视图
帐户定义为:
router = routers.DefaultRouter()
router.register('accounts', AccountViewSet)
Run Code Online (Sandbox Code Playgroud)
目标是:
bar_config/1上bar_config(列表页上PUT);bar_config/1;我将总结一下:我需要改变现有项目中子链接的工作方式,该方法已经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 Responce(serializer.data)
Run Code Online (Sandbox Code Playgroud)
它会工作正常,你不仅要显示该模型.如果你想提供一些CRUD,那么继承ModelViewSet和覆盖delete和update方法.
更新评论
另一种方法 - 创建自定义路由器,使用此路由器不需要使用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'}
),
]
Run Code Online (Sandbox Code Playgroud)
视图集:
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)
Run Code Online (Sandbox Code Playgroud)
网址:
router = CustomRouter()
router.register('config', ConfigViewSet)
urlpatterns = router.urls
Run Code Online (Sandbox Code Playgroud)