You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/api-guide/routers.md
+39-57Lines changed: 39 additions & 57 deletions
Original file line number
Diff line number
Diff line change
@@ -81,81 +81,62 @@ Router URL patterns can also be namespaces.
81
81
82
82
If using namespacing with hyperlinked serializers you'll also need to ensure that any `view_name` parameters on the serializers correctly reflect the namespace. In the example above you'd need to include a parameter such as `view_name='api:user-detail'` for serializer fields hyperlinked to the user detail view.
83
83
84
-
### Extra link and actions
84
+
### Routing for extra actions
85
85
86
-
Any methods on the viewset decorated with `@detail_route` or `@list_route` will also be routed.
87
-
For example, given a method like this on the `UserViewSet` class:
86
+
A viewset may [mark extra actions for routing][route-decorators] by decorating a method with the `@action` decorator. These extra actions will be included in the generated routes. For example, given the `set_password` method on the `UserViewSet` class:
88
87
89
88
from myapp.permissions import IsAdminOrIsSelf
90
-
from rest_framework.decorators import detail_route
If you do not want to use the default URL generated for your custom action, you can instead use the url_path parameter to customize it.
103
+
By default, the URL pattern is based on the method name, and the URL name is the combination of the `ViewSet.basename` and the hyphenated method name.
104
+
If you don't want to use the defaults for either of these values, you can instead provide the `url_path` and `url_name` arguments to the `@action` decorator.
104
105
105
106
For example, if you want to change the URL for our custom action to `^users/{pk}/change-password/$`, you could write:
106
107
107
108
from myapp.permissions import IsAdminOrIsSelf
108
-
from rest_framework.decorators import detail_route
You can also use url_path and url_name parameters together to obtain extra control on URL generation for custom views.
140
-
141
-
For more information see the viewset documentation on [marking extra actions for routing][route-decorators].
121
+
* URL path: `^users/{pk}/change-password/$`
122
+
* URL name: `'user-change_password'`
142
123
143
124
# API Guide
144
125
145
126
## SimpleRouter
146
127
147
-
This router includes routes for the standard set of `list`, `create`, `retrieve`, `update`, `partial_update` and `destroy` actions. The viewset can also mark additional methods to be routed, using the `@detail_route` or `@list_route` decorators.
128
+
This router includes routes for the standard set of `list`, `create`, `retrieve`, `update`, `partial_update` and `destroy` actions. The viewset can also mark additional methods to be routed, using the `@action` decorator.
<tr><td>{prefix}/{methodname}/</td><td>GET, or as specified by `methods` argument</td><td>`@list_route` decorated method</td><td>{basename}-{methodname}</td></tr>
134
+
<tr><td>{prefix}/{url_path}/</td><td>GET, or as specified by `methods` argument</td><td>`@action(detail=False)` decorated method</td><td>{basename}-{url_name}</td></tr>
<tr><td>{prefix}/{lookup}/{methodname}/</td><td>GET, or as specified by `methods` argument</td><td>`@detail_route` decorated method</td><td>{basename}-{methodname}</td></tr>
139
+
<tr><td>{prefix}/{lookup}/{url_path}/</td><td>GET, or as specified by `methods` argument</td><td>`@action(detail=True)` decorated method</td><td>{basename}-{url_name}</td></tr>
159
140
</table>
160
141
161
142
By default the URLs created by `SimpleRouter` are appended with a trailing slash.
@@ -180,12 +161,12 @@ This router is similar to `SimpleRouter` as above, but additionally includes a d
<tr><td>{prefix}/{methodname}/[.format]</td><td>GET, or as specified by `methods` argument</td><td>`@list_route` decorated method</td><td>{basename}-{methodname}</td></tr>
164
+
<tr><td>{prefix}/{url_path}/[.format]</td><td>GET, or as specified by `methods` argument</td><td>`@action(detail=False)` decorated method</td><td>{basename}-{url_name}</td></tr>
<tr><td>{prefix}/{lookup}/{methodname}/[.format]</td><td>GET, or as specified by `methods` argument</td><td>`@detail_route` decorated method</td><td>{basename}-{methodname}</td></tr>
169
+
<tr><td>{prefix}/{lookup}/{url_path}/[.format]</td><td>GET, or as specified by `methods` argument</td><td>`@action(detail=True)` decorated method</td><td>{basename}-{url_name}</td></tr>
189
170
</table>
190
171
191
172
As with `SimpleRouter` the trailing slashes on the URL routes can be removed by setting the `trailing_slash` argument to `False` when instantiating the router.
@@ -212,49 +193,50 @@ The arguments to the `Route` named tuple are:
212
193
213
194
*`{basename}` - The base to use for the URL names that are created.
214
195
215
-
**initkwargs**: A dictionary of any additional arguments that should be passed when instantiating the view. Note that the `suffix`argument is reserved for identifying the viewset type, used when generating the view name and breadcrumb links.
196
+
**initkwargs**: A dictionary of any additional arguments that should be passed when instantiating the view. Note that the `detail`, `basename`, and `suffix`arguments are reserved for viewset introspection and are also used by the browsable API to generate the view name and breadcrumb links.
216
197
217
198
## Customizing dynamic routes
218
199
219
-
You can also customize how the `@list_route` and `@detail_route` decorators are routed.
220
-
To route either or both of these decorators, include a `DynamicListRoute` and/or `DynamicDetailRoute` named tuple in the `.routes` list.
200
+
You can also customize how the `@action` decorator is routed. Include the `DynamicRoute` named tuple in the `.routes` list, setting the `detail` argument as appropriate for the list-based and detail-based routes. In addition to `detail`, the arguments to `DynamicRoute` are:
221
201
222
-
The arguments to `DynamicListRoute` and `DynamicDetailRoute` are:
202
+
**url**: A string representing the URL to be routed. May include the same format strings as `Route`, and additionally accepts the `{url_path}` format string.
223
203
224
-
**url**: A string representing the URL to be routed. May include the same format strings as `Route`, and additionally accepts the `{methodname}` and `{methodnamehyphen}`format strings.
204
+
**name**: The name of the URL as used in `reverse` calls. May include the following format strings:
225
205
226
-
**name**: The name of the URL as used in `reverse` calls. May include the following format strings: `{basename}`, `{methodname}` and `{methodnamehyphen}`.
206
+
*`{basename}` - The base to use for the URL names that are created.
207
+
*`{url_name}` - The `url_name` provided to the `@action`.
227
208
228
209
**initkwargs**: A dictionary of any additional arguments that should be passed when instantiating the view.
229
210
230
211
## Example
231
212
232
213
The following example will only route to the `list` and `retrieve` actions, and does not use the trailing slash convention.
233
214
234
-
from rest_framework.routers import Route, DynamicDetailRoute, SimpleRouter
215
+
from rest_framework.routers import Route, DynamicRoute, SimpleRouter
235
216
236
217
class CustomReadOnlyRouter(SimpleRouter):
237
218
"""
238
219
A router for read-only APIs, which doesn't use trailing slashes.
239
220
"""
240
221
routes = [
241
222
Route(
242
-
url=r'^{prefix}$',
243
-
mapping={'get': 'list'},
244
-
name='{basename}-list',
245
-
initkwargs={'suffix': 'List'}
223
+
url=r'^{prefix}$',
224
+
mapping={'get': 'list'},
225
+
name='{basename}-list',
226
+
initkwargs={'suffix': 'List'}
246
227
),
247
228
Route(
248
-
url=r'^{prefix}/{lookup}$',
229
+
url=r'^{prefix}/{lookup}$',
249
230
mapping={'get': 'retrieve'},
250
231
name='{basename}-detail',
251
232
initkwargs={'suffix': 'Detail'}
252
233
),
253
-
DynamicDetailRoute(
254
-
url=r'^{prefix}/{lookup}/{methodnamehyphen}$',
255
-
name='{basename}-{methodnamehyphen}',
256
-
initkwargs={}
257
-
)
234
+
DynamicRoute(
235
+
url=r'^{prefix}/{lookup}/{url_path}$',
236
+
name='{basename}-{url_name}',
237
+
detail=True,
238
+
initkwargs={}
239
+
)
258
240
]
259
241
260
242
Let's take a look at the routes our `CustomReadOnlyRouter` would generate for a simple viewset.
@@ -269,7 +251,7 @@ Let's take a look at the routes our `CustomReadOnlyRouter` would generate for a
269
251
serializer_class = UserSerializer
270
252
lookup_field = 'username'
271
253
272
-
@detail_route()
254
+
@action(detail=True)
273
255
def group_names(self, request, pk=None):
274
256
"""
275
257
Returns a list of all the group names that the given
@@ -283,7 +265,7 @@ Let's take a look at the routes our `CustomReadOnlyRouter` would generate for a
Copy file name to clipboardExpand all lines: docs/api-guide/viewsets.md
+29-17Lines changed: 29 additions & 17 deletions
Original file line number
Diff line number
Diff line change
@@ -102,10 +102,16 @@ The default routers included with REST framework will provide routes for a stand
102
102
def destroy(self, request, pk=None):
103
103
pass
104
104
105
-
During dispatch the name of the current action is available via the `.action` attribute.
106
-
You may inspect `.action` to adjust behaviour based on the current action.
105
+
## Introspecting ViewSet actions
107
106
108
-
For example, you could restrict permissions to everything except the `list` action similar to this:
107
+
During dispatch, the following attributes are available on the `ViewSet`.
108
+
109
+
*`basename` - the base to use for the URL names that are created.
110
+
*`action` - the name of the current action (e.g., `list`, `create`).
111
+
*`detail` - boolean indicating if the current action is configured for a list or detail view.
112
+
*`suffix` - the display suffix for the viewset type - mirrors the `detail` attribute.
113
+
114
+
You may inspect these attributes to adjust behaviour based on the current action. For example, you could restrict permissions to everything except the `list` action similar to this:
109
115
110
116
def get_permissions(self):
111
117
"""
@@ -119,16 +125,13 @@ For example, you could restrict permissions to everything except the `list` acti
119
125
120
126
## Marking extra actions for routing
121
127
122
-
If you have ad-hoc methods that you need to be routed to, you can mark them as requiring routing using the `@detail_route` or `@list_route` decorators.
123
-
124
-
The `@detail_route` decorator contains `pk` in its URL pattern and is intended for methods which require a single instance. The `@list_route` decorator is intended for methods which operate on a list of objects.
128
+
If you have ad-hoc methods that should be routable, you can mark them as such with the `@action` decorator. Like regular actions, extra actions may be intended for either a list of objects, or a single instance. To indicate this, set the `detail` argument to `True` or `False`. The router will configure its URL patterns accordingly. e.g., the `DefaultRouter` will configure detail actions to contain `pk` in their URL patterns.
125
129
126
-
For example:
130
+
A more complete example of extra actions:
127
131
128
132
from django.contrib.auth.models import User
129
-
from rest_framework import status
130
-
from rest_framework import viewsets
131
-
from rest_framework.decorators import detail_route, list_route
133
+
from rest_framework import status, viewsets
134
+
from rest_framework.decorators import action
132
135
from rest_framework.response import Response
133
136
from myapp.serializers import UserSerializer, PasswordSerializer
These decorators will route `GET` requests by default, but may also accept other HTTP methods, by using the `methods` argument. For example:
175
+
These decorator will route `GET` requests by default, but may also accept other HTTP methods by setting the `methods` argument. For example:
173
176
174
-
@detail_route(methods=['post', 'delete'])
177
+
@action(methods=['post', 'delete'], detail=True)
175
178
def unset_password(self, request, pk=None):
176
179
...
177
180
178
181
The two new actions will then be available at the urls `^users/{pk}/set_password/$` and `^users/{pk}/unset_password/$`
179
182
183
+
To view all extra actions, call the `.get_extra_actions()` method.
184
+
180
185
## Reversing action URLs
181
186
182
187
If you need to get the URL of an action, use the `.reverse_action()` method. This is a convenience wrapper for `reverse()`, automatically passing the view's `request` object and prepending the `url_name` with the `.basename` attribute.
@@ -190,7 +195,14 @@ Using the example from the previous section:
190
195
'http://localhost:8000/api/users/1/set_password'
191
196
```
192
197
193
-
The `url_name` argument should match the same argument to the `@list_route` and `@detail_route` decorators. Additionally, this can be used to reverse the default `list` and `detail` routes.
198
+
Alternatively, you can use the `url_name` attribute set by the `@action` decorator.
The `url_name` argument for `.reverse_action()` should match the same argument to the `@action` decorator. Additionally, this method can be used to reverse the default actions, such as `list` and `create`.
0 commit comments