aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2013-04-25 17:39:33 +0100
committerTom Christie2013-04-25 17:39:33 +0100
commit9abaf77401573e932ba4770248c1e229a8bc25dd (patch)
tree7046218b69f835c8485c7ca1a816d53b7e2499f9
parentb14b58498943c0a8f88c8ff931048bca4c90554b (diff)
downloaddjango-rest-framework-9abaf77401573e932ba4770248c1e229a8bc25dd.tar.bz2
More viewset/router docs
-rwxr-xr-xdocs/api-guide/generic-views.md4
-rw-r--r--docs/api-guide/routers.md34
-rw-r--r--docs/api-guide/viewsets.md63
-rw-r--r--docs/topics/2.3-announcement.md6
4 files changed, 101 insertions, 6 deletions
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 9d09af7f..4a24b7c7 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -147,8 +147,8 @@ You won't typically need to override the following methods, although you might n
* `get_serializer_context(self)` - Returns a dictionary containing any extra context that should be supplied to the serializer. Defaults to including `'request'`, `'view'` and `'format'` keys.
* `get_serializer(self, instance=None, data=None, files=None, many=False, partial=False)` - Returns a serializer instance.
* `get_pagination_serializer(self, page)` - Returns a serializer instance to use with paginated data.
-* `paginate_queryset(self, queryset, page_size)` - Paginate a queryset.
-* `filter_queryset(self, queryset)` - Given a queryset, filter it with whichever filter backend is in use.
+* `paginate_queryset(self, queryset)` - Paginate a queryset if required, either returning a page object, or `None` if pagination is not configured for this view.
+* `filter_queryset(self, queryset)` - Given a queryset, filter it with whichever filter backend is in use, returning a new queryset.
---
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 7411bd7b..16ad2fb8 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -14,15 +14,45 @@ REST framework adds support for automatic URL routing to Django, and provides yo
Here's an example of a simple URL conf, that uses `DefaultRouter`.
- router = routers.DefaultRouter()
+ router = routers.SimpleRouter()
router.register(r'users', UserViewSet, 'user')
router.register(r'accounts', AccountViewSet, 'account')
urlpatterns = router.urls
+There are three arguments to the `register()` method:
+
+* `prefix` - The URL prefix to use for this set of routes.
+* `viewset` - The viewset class.
+* `basename` - The base to use for the URL names that are created.
+
+The example above would generate the following URL patterns:
+
+* URL pattern: `^users/$` Name: `'user-list'`
+* URL pattern: `^users/{pk}/$` Name: `'user-detail'`
+* URL pattern: `^accounts/$` Name: `'account-list'`
+* URL pattern: `^accounts/{pk}/$` Name: `'account-detail'`
+
+### Extra link and actions
+
+Any `@link` or `@action` methods on the viewsets will also be routed.
+For example, a given method like this on the `UserViewSet` class:
+
+ @action(permission_classes=[IsAdminOrIsSelf])
+ def set_password(self, request, pk=None):
+ ...
+
+The following URL pattern would additionally be generated:
+
+* URL pattern: `^users/{pk}/set_password/$` Name: `'user-set-password'`
+
+
+
# API Guide
## SimpleRouter
+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 `@link` or `@action` decorators.
+
<table border=1>
<tr><th>URL Style</th><th>HTTP Method</th><th>Action</th><th>URL Name</th></tr>
<tr><td rowspan=2>{prefix}/</td><td>GET</td><td>list</td><td rowspan=2>{basename}-list</td></tr></tr>
@@ -37,6 +67,8 @@ Here's an example of a simple URL conf, that uses `DefaultRouter`.
## DefaultRouter
+This router is similar to `SimpleRouter` as above, but additionally includes a default API root view, that returns a response containing hyperlinks to all the list views. It also generates routes for optional `.json` style format suffixes.
+
<table border=1>
<tr><th>URL Style</th><th>HTTP Method</th><th>Action</th><th>URL Name</th></tr>
<tr><td>[.format]</td><td>GET</td><td>automatically generated root view</td><td>api-root</td></tr></tr>
diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md
index 2f0f112b..fe182e79 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -52,6 +52,67 @@ There are two main advantages of using a `ViewSet` class over using a `View` cla
Both of these come with a trade-off. Using regular views and URL confs is more explicit and gives you more control. ViewSets are helpful if you want to get up and running quickly, or when you have a large API and you want to enforce a consistent URL configuration throughout.
+## Marking extra methods for routing
+
+The default routers included with REST framework will provide routes for a standard set of create/retrieve/update/destroy style operations, as shown below:
+
+ class UserViewSet(viewsets.VietSet):
+ """
+ Example empty viewset demonstrating the standard
+ actions that will be handled by a router class.
+ """
+
+ def list(self, request):
+ pass
+
+ def create(self, request):
+ pass
+
+ def retrieve(self, request, pk=None):
+ pass
+
+ def update(self, request, pk=None):
+ pass
+
+ def partial_update(self, request, pk=None):
+ pass
+
+ def destroy(self, request, pk=None):
+ pass
+
+If you have ad-hoc methods that you need to be routed to, you can mark them as requiring routing using the `@link` or `@action` decorators. The `@link` decorator will route `GET` requests, and the `@action` decroator will route `POST` requests.
+
+For example:
+
+ from django.contrib.auth.models import User
+ from rest_framework import viewsets
+ from rest_framework.decorators import action
+ from myapp.serializers import UserSerializer
+
+ class UserViewSet(viewsets.ModelViewSet):
+ """
+ A viewset that provides the standard actions
+ """
+ queryset = User.objects.all()
+ serializer_class = UserSerializer
+
+ @action
+ def set_password(self, request, pk=None):
+ user = self.get_object()
+ serializer = PasswordSerializer(data=request.DATA)
+ if serializer.is_valid():
+ user.set_password(serializer.data['password'])
+ user.save()
+ return Response({'status': 'password set'})
+ else:
+ return Response(serializer.errors,
+ status=status.HTTP_400_BAD_REQUEST)
+
+The `@action` and `@link` decorators can additionally take extra arguments that will be set for the routed view only. For example...
+
+ @action(permission_classes=[IsAdminOrIsSelf])
+ def set_password(self, request, pk=None):
+ ...
# API Reference
@@ -134,6 +195,4 @@ For example, we can create a base viewset class that provides `retrieve`, `updat
By creating your own base `ViewSet` classes, you can provide common behavior that can be reused in multiple views across your API.
-For advanced usage, it's worth noting the that `ViewSetMixin` class can also be applied to the standard Django `View` class. Doing so allows you to use REST framework's automatic routing with regular Django views.
-
[cite]: http://guides.rubyonrails.org/routing.html \ No newline at end of file
diff --git a/docs/topics/2.3-announcement.md b/docs/topics/2.3-announcement.md
index e8e8c091..66875c82 100644
--- a/docs/topics/2.3-announcement.md
+++ b/docs/topics/2.3-announcement.md
@@ -86,6 +86,10 @@ The `get_object` and `get_paginate_by` methods no longer take an optional querys
Using an optional queryset with these methods continues to be supported, but will raise a `PendingDeprecationWarning`.
+The `paginate_queryset` method no longer takes a `page_size` argument, or returns a four-tuple of pagination information. Instead it simply takes a queryset argument, and either returns a `page` object with an appropraite page size, or returns `None`, if pagination is not configured for the view.
+
+Using the `page_size` argument is still supported and will trigger the old-style return type, but will raise a `PendingDeprecationWarning`.
+
### Deprecated attributes
The following attributes are used to control queryset lookup, and have all been moved into a pending deprecation state.
@@ -137,7 +141,7 @@ It also makes it the usage of overridden `get_queryset()` or `get_serializer_cla
"""
Determine the queryset dynamically, depending on the
user making the request.
-
+
Note that overriding this method follows on more obviously now
that an explicit `queryset` attribute is the usual view style.
"""