有一个使用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)
目标是:
bar_config/1
上显示bar_config
(LIST页面上的PUT); bar_config/1
; 我将总结一下:我需要改变子链接在现有项目中的工作方式,该项目已经为其所有模式使用DefaultRouter
。该子链接映射单例模型。我想在列表(GET)页面上显示更新(PUT)数据。
答案 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
并覆盖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'}
),
]
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