From 635dc0352927463a4ca210f4035afdbe3e13e218 Mon Sep 17 00:00:00 2001 From: Luca Date: Thu, 19 Jan 2017 16:20:34 +0100 Subject: [PATCH] Parametrizable viewset custom views reverse name (#4821) --- docs/api-guide/routers.md | 20 ++++++++++++++++++++ rest_framework/routers.py | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 10a86bdf0..d3f4186ad 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -118,6 +118,26 @@ The above example would now generate the following URL pattern: * URL pattern: `^users/{pk}/change-password/$` Name: `'user-change-password'` +In the case you do not want to use the default name generated for your custom action, you can use the url_name parameter to customize it. + +For example, if you want to change the name of our custom action to `'user-change-password'`, you could write: + + from myapp.permissions import IsAdminOrIsSelf + from rest_framework.decorators import detail_route + + class UserViewSet(ModelViewSet): + ... + + @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf], url_name='change-password') + def set_password(self, request, pk=None): + ... + +The above example would now generate the following URL pattern: + +* URL pattern: `^users/{pk}/set_password/$` Name: `'user-change-password'` + +You can also use url_path and url_name parameters together to obtain extra control on URL generation for custom views. + For more information see the viewset documentation on [marking extra actions for routing][route-decorators]. # API Guide diff --git a/rest_framework/routers.py b/rest_framework/routers.py index 7a2d981a3..4e3fbc4de 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -179,10 +179,11 @@ class SimpleRouter(BaseRouter): initkwargs = route.initkwargs.copy() initkwargs.update(method_kwargs) url_path = initkwargs.pop("url_path", None) or methodname + url_name = initkwargs.pop("url_name", None) or url_path ret.append(Route( url=replace_methodname(route.url, url_path), mapping={httpmethod: methodname for httpmethod in httpmethods}, - name=replace_methodname(route.name, url_path), + name=replace_methodname(route.name, url_name), initkwargs=initkwargs, ))