在文档中有自定义网址的方法示例: http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers
class SnippetViewSet(viewsets.ModelViewSet):
...
@link(renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted)
此示例添加以下路由:
url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', snippet_highlight, name='snippet-highlight'),
可以添加一个没有pk param的url,像这样吗?
r'^snippets/highlight/$'
答案 0 :(得分:9)
是的,你可以这样做。只需使用list_route
装饰器在视图集中添加您的方法。
from rest_framework.decorators import list_route
class SnippetViewSet(viewsets.ModelViewSet):
...
@list_route(renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
...
它会添加一个没有pk
参数的网址,如:
r'^snippets/highlight/$'
您甚至可以使用装饰器中的methods
参数指定它支持的方法。
http://www.django-rest-framework.org/api-guide/routers/#usage
答案 1 :(得分:4)
使用action
装饰器的ViewSets docs提及:
from rest_framework.decorators import action
class SnippetViewSet(viewsets.ModelViewSet):
...
@action(detail=False, methods=['GET'], name='Get Highlight')
def highlight(self, request, *args, **kwargs):
queryset = models.Highlight.objects.all()
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
然后只需更新查询集即可执行所需的任何操作。
这样做的优点是保留了序列化。
如果您的urls.py
如下所示:
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from snippets import viewsets
router = routers.DefaultRouter()
router.register('snippets', viewsets.SnippetViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('snippets/', include(router.urls)),
]
然后可以通过http://localhost:8000/snippets/highlights
要查看POST
的用法或如何更改路由,请参阅docs for routers。
答案 2 :(得分:4)
由于此问题仍然出现在第一个Google Page上,因此以下(针对2020年3月下旬)的最新代码段(双关语旨在)开始为您的单个对象创建自定义ModelViewSet路线:
from rest_framework.decorators import action
class SnippetViewSet(viewsets.ModelViewSet):
...
@action(detail=True, methods=['POST'], name='Attach meta items ids')
def custom_action(self, request, pk=None):
"""Does something on single item."""
queryset = Snippet.objects.get(pk=pk)
serializer = self.get_serializer(queryset, many=False)
return Response(serializer.data)
从DRF教程获得默认路由器后,您可以通过以下方式访问此路由:http://localhost:8000/snippets/<int:pk>/custom_action/