From 5b11e23f6fb35834057fba35832a597ce443cc77 Mon Sep 17 00:00:00 2001
From: Alex Burgel
Date: Wed, 5 Jun 2013 17:41:29 -0400
Subject: Add docs for collection routes
---
docs/api-guide/viewsets.md | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md
index 47e59e2b..9fa6615b 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -92,7 +92,9 @@ The default routers included with REST framework will provide routes for a stand
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` decorator will route `POST` requests.
+If you have ad-hoc methods that you need to be routed to, you can mark them as requiring routing using the `@collection_link`, `@collection_action`, `@link`, or `@action` decorators. The `@collection_link` and `@link` decorator will route `GET` requests, and the `@collection_action` and `@action` decorator will route `POST` requests.
+
+The `@link` and `@action` decorators contain `pk` in their URL pattern and are intended for methods which require a single instance. The `@collection_link` and `@collection_action` decorators are intended for methods which operate on a collection of objects.
For example:
@@ -121,13 +123,20 @@ For example:
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...
+ @collection_link()
+ def recent_users(self, request):
+ recent_users = User.objects.all().order('-last_login')
+ page = self.paginate_queryset(recent_users)
+ serializer = self.get_pagination_serializer(page)
+ return Response(serializer.data)
+
+The 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):
...
-The `@action` decorator will route `POST` requests by default, but may also accept other HTTP methods, by using the `method` argument. For example:
+The `@collection_action` and `@action` decorators will route `POST` requests by default, but may also accept other HTTP methods, by using the `method` argument. For example:
@action(methods=['POST', 'DELETE'])
def unset_password(self, request, pk=None):
--
cgit v1.2.3
From 57cf8b5fa4f62f9b58912f10536a7ae5076ce54c Mon Sep 17 00:00:00 2001
From: Alex Burgel
Date: Thu, 6 Jun 2013 11:51:52 -0400
Subject: Rework extra routes doc for better readability
---
docs/api-guide/viewsets.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md
index 9fa6615b..e83487fb 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -92,7 +92,7 @@ The default routers included with REST framework will provide routes for a stand
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 `@collection_link`, `@collection_action`, `@link`, or `@action` decorators. The `@collection_link` and `@link` decorator will route `GET` requests, and the `@collection_action` and `@action` decorator will route `POST` requests.
+If you have ad-hoc methods that you need to be routed to, you can mark them as requiring routing using the `@link`, `@action`, `@collection_link`, or `@collection_action` decorators. The `@link` and `@collection_link` decorators will route `GET` requests, and the `@action` and `@collection_action` decorators will route `POST` requests.
The `@link` and `@action` decorators contain `pk` in their URL pattern and are intended for methods which require a single instance. The `@collection_link` and `@collection_action` decorators are intended for methods which operate on a collection of objects.
@@ -136,7 +136,7 @@ The decorators can additionally take extra arguments that will be set for the ro
def set_password(self, request, pk=None):
...
-The `@collection_action` and `@action` decorators will route `POST` requests by default, but may also accept other HTTP methods, by using the `method` argument. For example:
+The `@action` and `@collection_action` decorators will route `POST` requests by default, but may also accept other HTTP methods, by using the `methods` argument. For example:
@action(methods=['POST', 'DELETE'])
def unset_password(self, request, pk=None):
--
cgit v1.2.3
From e14cbaf6961ad9c94deaf0417d8e8ce5ec96d0ac Mon Sep 17 00:00:00 2001
From: Alex Burgel
Date: Sat, 13 Jul 2013 11:11:53 -0400
Subject: Changed collection_* decorators to list_*
---
docs/api-guide/viewsets.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md
index e83487fb..6d6bb133 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -92,15 +92,15 @@ The default routers included with REST framework will provide routes for a stand
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`, `@action`, `@collection_link`, or `@collection_action` decorators. The `@link` and `@collection_link` decorators will route `GET` requests, and the `@action` and `@collection_action` decorators will route `POST` requests.
+If you have ad-hoc methods that you need to be routed to, you can mark them as requiring routing using the `@link`, `@action`, `@list_link`, or `@list_action` decorators. The `@link` and `@list_link` decorators will route `GET` requests, and the `@action` and `@list_action` decorators will route `POST` requests.
-The `@link` and `@action` decorators contain `pk` in their URL pattern and are intended for methods which require a single instance. The `@collection_link` and `@collection_action` decorators are intended for methods which operate on a collection of objects.
+The `@link` and `@action` decorators contain `pk` in their URL pattern and are intended for methods which require a single instance. The `@list_link` and `@list_action` decorators are intended for methods which operate on a list of objects.
For example:
from django.contrib.auth.models import User
from rest_framework import viewsets
- from rest_framework.decorators import action
+ from rest_framework.decorators import action, list_link
from rest_framework.response import Response
from myapp.serializers import UserSerializer, PasswordSerializer
@@ -123,7 +123,7 @@ For example:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
- @collection_link()
+ @list_link()
def recent_users(self, request):
recent_users = User.objects.all().order('-last_login')
page = self.paginate_queryset(recent_users)
@@ -136,7 +136,7 @@ The decorators can additionally take extra arguments that will be set for the ro
def set_password(self, request, pk=None):
...
-The `@action` and `@collection_action` decorators will route `POST` requests by default, but may also accept other HTTP methods, by using the `methods` argument. For example:
+The `@action` and `@list_action` decorators will route `POST` requests by default, but may also accept other HTTP methods, by using the `methods` argument. For example:
@action(methods=['POST', 'DELETE'])
def unset_password(self, request, pk=None):
--
cgit v1.2.3
From eaae8fb2d973769a827214e0606a7e41028d5d34 Mon Sep 17 00:00:00 2001
From: Alex Burgel
Date: Mon, 15 Jul 2013 18:35:13 -0400
Subject: Combined link_* and action_* decorators into detail_route and
list_route, marked the originals as deprecated.
---
docs/api-guide/routers.md | 16 ++++++++--------
docs/api-guide/viewsets.md | 16 ++++++++--------
docs/tutorial/6-viewsets-and-routers.md | 8 ++++----
3 files changed, 20 insertions(+), 20 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 86582905..f196dc3c 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -35,12 +35,12 @@ The example above would generate the following URL patterns:
* URL pattern: `^accounts/$` Name: `'account-list'`
* URL pattern: `^accounts/{pk}/$` Name: `'account-detail'`
-### Extra link and actions
+### Registering additional routes
-Any methods on the viewset decorated with `@link` or `@action` will also be routed.
+Any methods on the viewset decorated with `@detail_route` or `@list_route` will also be routed.
For example, a given method like this on the `UserViewSet` class:
- @action(permission_classes=[IsAdminOrIsSelf])
+ @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
...
@@ -52,7 +52,7 @@ The following URL pattern would additionally be generated:
## 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.
+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.
| URL Style | HTTP Method | Action | URL Name |
@@ -62,8 +62,8 @@ This router includes routes for the standard set of `list`, `create`, `retrieve`
| PUT | update |
| PATCH | partial_update |
| DELETE | destroy |
- | {prefix}/{lookup}/{methodname}/ | GET | @link decorated method | {basename}-{methodname} |
- | POST | @action decorated method |
+ | {prefix}/{lookup}/{methodname}/ | GET | @detail_route decorated method | {basename}-{methodname} |
+ | POST | @detail_route decorated method |
By default the URLs created by `SimpleRouter` are appending with a trailing slash.
@@ -86,8 +86,8 @@ This router is similar to `SimpleRouter` as above, but additionally includes a d
| PUT | update |
| PATCH | partial_update |
| DELETE | destroy |
- | {prefix}/{lookup}/{methodname}/[.format] | GET | @link decorated method | {basename}-{methodname} |
- | POST | @action decorated method |
+ | {prefix}/{lookup}/{methodname}/[.format] | GET | @detail_route decorated method | {basename}-{methodname} |
+ | POST | @detail_route decorated method |
As with `SimpleRouter` the trailing slashs on the URL routes can be removed by setting the `trailing_slash` argument to `False` when instantiating the router.
diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md
index 6d6bb133..7a8d5979 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -92,15 +92,15 @@ The default routers included with REST framework will provide routes for a stand
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`, `@action`, `@list_link`, or `@list_action` decorators. The `@link` and `@list_link` decorators will route `GET` requests, and the `@action` and `@list_action` decorators will route `POST` requests.
+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.
-The `@link` and `@action` decorators contain `pk` in their URL pattern and are intended for methods which require a single instance. The `@list_link` and `@list_action` decorators are intended for methods which operate on a list of objects.
+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.
For example:
from django.contrib.auth.models import User
from rest_framework import viewsets
- from rest_framework.decorators import action, list_link
+ from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
from myapp.serializers import UserSerializer, PasswordSerializer
@@ -111,7 +111,7 @@ For example:
queryset = User.objects.all()
serializer_class = UserSerializer
- @action()
+ @detail_route(methods=['post'])
def set_password(self, request, pk=None):
user = self.get_object()
serializer = PasswordSerializer(data=request.DATA)
@@ -123,7 +123,7 @@ For example:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
- @list_link()
+ @list_route()
def recent_users(self, request):
recent_users = User.objects.all().order('-last_login')
page = self.paginate_queryset(recent_users)
@@ -132,13 +132,13 @@ For example:
The decorators can additionally take extra arguments that will be set for the routed view only. For example...
- @action(permission_classes=[IsAdminOrIsSelf])
+ @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
...
-The `@action` and `@list_action` decorators will route `POST` requests by default, but may also accept other HTTP methods, by using the `methods` argument. For example:
+By default, the decorators will route `GET` requests, but may also accept other HTTP methods, by using the `methods` argument. For example:
- @action(methods=['POST', 'DELETE'])
+ @detail_route(methods=['post', 'delete'])
def unset_password(self, request, pk=None):
...
---
diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md
index f16add39..f126ba04 100644
--- a/docs/tutorial/6-viewsets-and-routers.md
+++ b/docs/tutorial/6-viewsets-and-routers.md
@@ -25,7 +25,7 @@ Here we've used `ReadOnlyModelViewSet` class to automatically provide the defaul
Next we're going to replace the `SnippetList`, `SnippetDetail` and `SnippetHighlight` view classes. We can remove the three views, and again replace them with a single class.
- from rest_framework.decorators import link
+ from rest_framework.decorators import detail_route
class SnippetViewSet(viewsets.ModelViewSet):
"""
@@ -39,7 +39,7 @@ Next we're going to replace the `SnippetList`, `SnippetDetail` and `SnippetHighl
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
- @link(renderer_classes=[renderers.StaticHTMLRenderer])
+ @detail_route(renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted)
@@ -49,9 +49,9 @@ Next we're going to replace the `SnippetList`, `SnippetDetail` and `SnippetHighl
This time we've used the `ModelViewSet` class in order to get the complete set of default read and write operations.
-Notice that we've also used the `@link` decorator to create a custom action, named `highlight`. This decorator can be used to add any custom endpoints that don't fit into the standard `create`/`update`/`delete` style.
+Notice that we've also used the `@detail_route` decorator to create a custom action, named `highlight`. This decorator can be used to add any custom endpoints that don't fit into the standard `create`/`update`/`delete` style.
-Custom actions which use the `@link` decorator will respond to `GET` requests. We could have instead used the `@action` decorator if we wanted an action that responded to `POST` requests.
+Custom actions which use the `@detail_route` decorator will respond to `GET` requests. We can use the `methods` argument if we wanted an action that responded to `POST` requests.
## Binding ViewSets to URLs explicitly
--
cgit v1.2.3
From 4292cc18fa3e4b3f5e67c02c3780cdcbf901a0a1 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 19 Aug 2013 20:53:30 +0100
Subject: Docs tweaking
---
docs/api-guide/routers.md | 11 +++++++----
docs/api-guide/viewsets.md | 2 +-
2 files changed, 8 insertions(+), 5 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 7884c2e9..c8465418 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -48,6 +48,8 @@ The following URL pattern would additionally be generated:
* URL pattern: `^users/{pk}/set_password/$` Name: `'user-set-password'`
+For more information see the viewset documentation on [marking extra actions for routing][route-decorators].
+
# API Guide
## SimpleRouter
@@ -58,12 +60,12 @@ This router includes routes for the standard set of `list`, `create`, `retrieve`
| URL Style | HTTP Method | Action | URL Name |
| {prefix}/ | GET | list | {basename}-list |
| POST | create |
+ | {prefix}/{methodname}/ | GET, or as specified by `methods` argument | `@list_route` decorated method | {basename}-{methodname} |
| {prefix}/{lookup}/ | GET | retrieve | {basename}-detail |
| PUT | update |
| PATCH | partial_update |
| DELETE | destroy |
- | {prefix}/{lookup}/{methodname}/ | GET | @detail_route decorated method | {basename}-{methodname} |
- | POST | @detail_route decorated method |
+ | {prefix}/{lookup}/{methodname}/ | GET, or as specified by `methods` argument | `@detail_route` decorated method | {basename}-{methodname} |
By default the URLs created by `SimpleRouter` are appended with a trailing slash.
@@ -82,12 +84,12 @@ This router is similar to `SimpleRouter` as above, but additionally includes a d
| [.format] | GET | automatically generated root view | api-root |
| {prefix}/[.format] | GET | list | {basename}-list |
| POST | create |
+ | {prefix}/{methodname}/[.format] | GET, or as specified by `methods` argument | `@list_route` decorated method | {basename}-{methodname} |
| {prefix}/{lookup}/[.format] | GET | retrieve | {basename}-detail |
| PUT | update |
| PATCH | partial_update |
| DELETE | destroy |
- | {prefix}/{lookup}/{methodname}/[.format] | GET | @detail_route decorated method | {basename}-{methodname} |
- | POST | @detail_route decorated method |
+ | {prefix}/{lookup}/{methodname}/[.format] | GET, or as specified by `methods` argument | `@detail_route` decorated method | {basename}-{methodname} |
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.
@@ -144,3 +146,4 @@ If you want to provide totally custom behavior, you can override `BaseRouter` an
You may also want to override the `get_default_base_name(self, viewset)` method, or else always explicitly set the `base_name` argument when registering your viewsets with the router.
[cite]: http://guides.rubyonrails.org/routing.html
+[route-decorators]: viewsets.html#marking-extra-actions-for-routing
\ No newline at end of file
diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md
index 95efc229..9005e7cb 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -61,7 +61,7 @@ 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
+## Marking extra actions 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:
--
cgit v1.2.3
From 44ceef841543877a700c3fb4a0f84dfecbad0cbb Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Wed, 21 Aug 2013 21:30:25 +0100
Subject: Updating 2.4.0 release notes
---
docs/topics/release-notes.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 52abfc08..f3bb19c6 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -40,9 +40,12 @@ You can determine your currently installed version using `pip freeze`:
## 2.3.x series
-### Master
+### 2.4.0
+* `@detail_route` and `@list_route` decorators replace `@action` and `@link`.
+* `six` no longer bundled. For Django <= 1.4.1, install `six` package.
* Support customizable view name and description functions, using the `VIEW_NAME_FUNCTION` and `VIEW_DESCRIPTION_FUNCTION` settings.
+* Bugfix: `?page_size=0` query parameter now falls back to default page size for view, instead of always turning pagination off.
### 2.3.7
--
cgit v1.2.3
From bf07b8e616bd92e4ae3c2c09b198181d7075e6bd Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Thu, 29 Aug 2013 08:53:19 +0100
Subject: Better docs for customizing dynamic routes. Refs #908
---
docs/api-guide/routers.md | 81 ++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 70 insertions(+), 11 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index f083b3d4..730fa876 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -123,28 +123,87 @@ The arguments to the `Route` named tuple are:
**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.
+## Customizing dynamic routes
+
+You can also customize how the `@list_route` and `@detail_route` decorators are routed.
+To route either or both of these decorators, include a `DynamicListRoute` and/or `DynamicDetailRoute` named tuple in the `.routes` list.
+
+The arguments to `DynamicListRoute` and `DynamicDetailRoute` are:
+
+**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.
+
+**name**: The name of the URL as used in `reverse` calls. May include the following format strings: `{basename}`, `{methodname}` and `{methodnamehyphen}`.
+
+**initkwargs**: A dictionary of any additional arguments that should be passed when instantiating the view.
+
## Example
The following example will only route to the `list` and `retrieve` actions, and does not use the trailing slash convention.
- from rest_framework.routers import Route, SimpleRouter
+ from rest_framework.routers import Route, DynamicDetailRoute, SimpleRouter
- class ReadOnlyRouter(SimpleRouter):
+ class CustomReadOnlyRouter(SimpleRouter):
"""
A router for read-only APIs, which doesn't use trailing slashes.
"""
routes = [
- Route(url=r'^{prefix}$',
- mapping={'get': 'list'},
- name='{basename}-list',
- initkwargs={'suffix': 'List'}),
- Route(url=r'^{prefix}/{lookup}$',
- mapping={'get': 'retrieve'},
- name='{basename}-detail',
- initkwargs={'suffix': 'Detail'})
+ Route(
+ url=r'^{prefix}$',
+ mapping={'get': 'list'},
+ name='{basename}-list',
+ initkwargs={'suffix': 'List'}
+ ),
+ Route(
+ url=r'^{prefix}/{lookup}$',
+ mapping={'get': 'retrieve'},
+ name='{basename}-detail',
+ initkwargs={'suffix': 'Detail'}
+ ),
+ DynamicDetailRoute(
+ url=r'^{prefix}/{lookup}/{methodnamehyphen}$',
+ name='{basename}-{methodnamehyphen}',
+ initkwargs={}
+ )
]
-The `SimpleRouter` class provides another example of setting the `.routes` attribute.
+Let's take a look at the routes our `CustomReadOnlyRouter` would generate for a simple viewset.
+
+`views.py`:
+
+ class UserViewSet(viewsets.ReadOnlyModelViewSet):
+ """
+ A viewset that provides the standard actions
+ """
+ queryset = User.objects.all()
+ serializer_class = UserSerializer
+ lookup_field = 'username'
+
+ @detail_route()
+ def group_names(self, request):
+ """
+ Returns a list of all the group names that the given
+ user belongs to.
+ """
+ user = self.get_object()
+ groups = user.groups.all()
+ return Response([group.name for group in groups])
+
+`urls.py`:
+
+ router = CustomReadOnlyRouter()
+ router.register('users', UserViewSet)
+ urlpatterns = router.urls
+
+The following mappings would be generated...
+
+
+ | URL | HTTP Method | Action | URL Name |
+ | /users | GET | list | user-list |
+ | /users/{username} | GET | retrieve | user-detail |
+ | /users/{username}/group-names | GET | group_names | user-group-names |
+
+
+For another example of setting the `.routes` attribute, see the source code for the `SimpleRouter` class.
## Advanced custom routers
--
cgit v1.2.3
From ab4be47379ba49092063f843fd446919534db776 Mon Sep 17 00:00:00 2001
From: Omer Katz
Date: Thu, 3 Oct 2013 17:34:34 +0200
Subject: Fixed code example.
---
docs/api-guide/routers.md | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 730fa876..f20a695b 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -42,12 +42,15 @@ The example above would generate the following URL patterns:
Any methods on the viewset decorated with `@detail_route` or `@list_route` will also be routed.
For example, given a method like this on the `UserViewSet` class:
- from myapp.permissions import IsAdminOrIsSelf
+ from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import detail_route
-
- @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf])
- def set_password(self, request, pk=None):
+
+ class UserViewSet(ModelViewSet):
...
+
+ @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf])
+ def set_password(self, request, pk=None):
+ ...
The following URL pattern would additionally be generated:
--
cgit v1.2.3
From 100a933279e3119e2627d744cd7eb472b542f6fe Mon Sep 17 00:00:00 2001
From: kahnjw
Date: Fri, 6 Dec 2013 14:22:08 -0800
Subject: Add documentation to explain what effect these changes have.
---
docs/api-guide/throttling.md | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md
index cc469217..ee57383c 100644
--- a/docs/api-guide/throttling.md
+++ b/docs/api-guide/throttling.md
@@ -35,11 +35,16 @@ The default throttling policy may be set globally, using the `DEFAULT_THROTTLE_C
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '1000/day'
- }
+ },
+ 'NUM_PROXIES': 2,
}
The rate descriptions used in `DEFAULT_THROTTLE_RATES` may include `second`, `minute`, `hour` or `day` as the throttle period.
+By default Django REST Framework will try to use the `HTTP_X_FORWARDED_FOR` header to uniquely identify client machines for throttling. If HTTP_X_FORWARDED_FOR is not present `REMOTE_ADDR` header value will be used.
+
+To help Django REST Framework identify unique clients the number of application proxies can be set using `NUM_PROXIES`. This setting will allow the throttle to correctly identify unique requests whenthere are multiple application side proxies in front of the server. `NUM_PROXIES` should be set to an integer. It is important to understand that if you configure `NUM_PROXIES > 0` all clients behind a unique [NAT'd](http://en.wikipedia.org/wiki/Network_address_translation) gateway will be treated as a single client.
+
You can also set the throttling policy on a per-view or per-viewset basis,
using the `APIView` class based views.
--
cgit v1.2.3
From 196c5952e4f610054e832aef36cb2383b8c129c0 Mon Sep 17 00:00:00 2001
From: kahnjw
Date: Fri, 6 Dec 2013 14:24:16 -0800
Subject: Fix typo
---
docs/api-guide/throttling.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md
index ee57383c..69b15a82 100644
--- a/docs/api-guide/throttling.md
+++ b/docs/api-guide/throttling.md
@@ -43,7 +43,7 @@ The rate descriptions used in `DEFAULT_THROTTLE_RATES` may include `second`, `mi
By default Django REST Framework will try to use the `HTTP_X_FORWARDED_FOR` header to uniquely identify client machines for throttling. If HTTP_X_FORWARDED_FOR is not present `REMOTE_ADDR` header value will be used.
-To help Django REST Framework identify unique clients the number of application proxies can be set using `NUM_PROXIES`. This setting will allow the throttle to correctly identify unique requests whenthere are multiple application side proxies in front of the server. `NUM_PROXIES` should be set to an integer. It is important to understand that if you configure `NUM_PROXIES > 0` all clients behind a unique [NAT'd](http://en.wikipedia.org/wiki/Network_address_translation) gateway will be treated as a single client.
+To help Django REST Framework identify unique clients the number of application proxies can be set using `NUM_PROXIES`. This setting will allow the throttle to correctly identify unique requests when there are multiple application side proxies in front of the server. `NUM_PROXIES` should be set to an integer. It is important to understand that if you configure `NUM_PROXIES > 0` all clients behind a unique [NAT'd](http://en.wikipedia.org/wiki/Network_address_translation) gateway will be treated as a single client.
You can also set the throttling policy on a per-view or per-viewset basis,
using the `APIView` class based views.
--
cgit v1.2.3
From 887da7f6c5a9e7b5007f5e4af32a6b93b18c70ea Mon Sep 17 00:00:00 2001
From: kahnjw
Date: Fri, 6 Dec 2013 14:30:33 -0800
Subject: Add missing tick marks
---
docs/api-guide/throttling.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md
index 69b15a82..34418e84 100644
--- a/docs/api-guide/throttling.md
+++ b/docs/api-guide/throttling.md
@@ -41,7 +41,7 @@ The default throttling policy may be set globally, using the `DEFAULT_THROTTLE_C
The rate descriptions used in `DEFAULT_THROTTLE_RATES` may include `second`, `minute`, `hour` or `day` as the throttle period.
-By default Django REST Framework will try to use the `HTTP_X_FORWARDED_FOR` header to uniquely identify client machines for throttling. If HTTP_X_FORWARDED_FOR is not present `REMOTE_ADDR` header value will be used.
+By default Django REST Framework will try to use the `HTTP_X_FORWARDED_FOR` header to uniquely identify client machines for throttling. If `HTTP_X_FORWARDED_FOR` is not present `REMOTE_ADDR` header value will be used.
To help Django REST Framework identify unique clients the number of application proxies can be set using `NUM_PROXIES`. This setting will allow the throttle to correctly identify unique requests when there are multiple application side proxies in front of the server. `NUM_PROXIES` should be set to an integer. It is important to understand that if you configure `NUM_PROXIES > 0` all clients behind a unique [NAT'd](http://en.wikipedia.org/wiki/Network_address_translation) gateway will be treated as a single client.
--
cgit v1.2.3
From 83da4949c099fcf7e7636c98b9052b502e1bf74b Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 13 Dec 2013 00:02:18 +0000
Subject: Allow NUM_PROXIES=0 and include more docs
---
docs/api-guide/settings.md | 6 ++++++
docs/api-guide/throttling.md | 18 ++++++++++++------
2 files changed, 18 insertions(+), 6 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 13f96f9a..d8c878ff 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -359,5 +359,11 @@ The name of a parameter in the URL conf that may be used to provide a format suf
Default: `'format'`
+#### NUM_PROXIES
+
+An integer of 0 or more, that may be used to specify the number of application proxies that the API runs behind. This allows throttling to more accurately identify client IP addresses. If set to `None` then less strict IP matching will be used by the throttle classes.
+
+Default: `None`
+
[cite]: http://www.python.org/dev/peps/pep-0020/
[strftime]: http://docs.python.org/2/library/time.html#time.strftime
diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md
index 34418e84..b2a5bb19 100644
--- a/docs/api-guide/throttling.md
+++ b/docs/api-guide/throttling.md
@@ -35,16 +35,11 @@ The default throttling policy may be set globally, using the `DEFAULT_THROTTLE_C
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '1000/day'
- },
- 'NUM_PROXIES': 2,
+ }
}
The rate descriptions used in `DEFAULT_THROTTLE_RATES` may include `second`, `minute`, `hour` or `day` as the throttle period.
-By default Django REST Framework will try to use the `HTTP_X_FORWARDED_FOR` header to uniquely identify client machines for throttling. If `HTTP_X_FORWARDED_FOR` is not present `REMOTE_ADDR` header value will be used.
-
-To help Django REST Framework identify unique clients the number of application proxies can be set using `NUM_PROXIES`. This setting will allow the throttle to correctly identify unique requests when there are multiple application side proxies in front of the server. `NUM_PROXIES` should be set to an integer. It is important to understand that if you configure `NUM_PROXIES > 0` all clients behind a unique [NAT'd](http://en.wikipedia.org/wiki/Network_address_translation) gateway will be treated as a single client.
-
You can also set the throttling policy on a per-view or per-viewset basis,
using the `APIView` class based views.
@@ -71,6 +66,16 @@ Or, if you're using the `@api_view` decorator with function based views.
}
return Response(content)
+## How clients are identified
+
+By default the `X-Forwarded-For` HTTP header is used to uniquely identify client machines for throttling. If the `X-Forwarded-For` header is not present, then the value of the `Remote-Addr` header will be used.
+
+If you need to more strictly identify unique clients, you'll need to configure the number of application proxies that the API runs behind by setting the `NUM_PROXIES` setting. This setting should be an integer of 0 or more, and will allow the throttle to identify the client IP as being the last IP address in the `X-Forwarded-For` header, once any application proxy IP addresses have first been excluded.
+
+It is important to understand that if you configure the `NUM_PROXIES` setting, then all clients behind a unique [NAT'd](http://en.wikipedia.org/wiki/Network_address_translation) gateway will be treated as a single client.
+
+Further context on how the `X-Forwarded-For` header works, and identifier a remote client IP can be [found here][identifing-clients].
+
## Setting up the cache
The throttle classes provided by REST framework use Django's cache backend. You should make sure that you've set appropriate [cache settings][cache-setting]. The default value of `LocMemCache` backend should be okay for simple setups. See Django's [cache documentation][cache-docs] for more details.
@@ -183,5 +188,6 @@ The following is an example of a rate throttle, that will randomly throttle 1 in
[cite]: https://dev.twitter.com/docs/error-codes-responses
[permissions]: permissions.md
+[identifing-clients]: http://oxpedia.org/wiki/index.php?title=AppSuite:Grizzly#Multiple_Proxies_in_front_of_the_cluster
[cache-setting]: https://docs.djangoproject.com/en/dev/ref/settings/#caches
[cache-docs]: https://docs.djangoproject.com/en/dev/topics/cache/#setting-up-the-cache
--
cgit v1.2.3
From ed931b90ae9e72f963673e6e188b1802a5a65360 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 13 Dec 2013 00:11:59 +0000
Subject: Further docs tweaks
---
docs/api-guide/throttling.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md
index b2a5bb19..536f0ab7 100644
--- a/docs/api-guide/throttling.md
+++ b/docs/api-guide/throttling.md
@@ -68,13 +68,13 @@ Or, if you're using the `@api_view` decorator with function based views.
## How clients are identified
-By default the `X-Forwarded-For` HTTP header is used to uniquely identify client machines for throttling. If the `X-Forwarded-For` header is not present, then the value of the `Remote-Addr` header will be used.
+The `X-Forwarded-For` and `Remote-Addr` HTTP headers are used to uniquely identify client IP addresses for throttling. If the `X-Forwarded-For` header is present then it will be used, otherwise the value of the `Remote-Addr` header will be used.
-If you need to more strictly identify unique clients, you'll need to configure the number of application proxies that the API runs behind by setting the `NUM_PROXIES` setting. This setting should be an integer of 0 or more, and will allow the throttle to identify the client IP as being the last IP address in the `X-Forwarded-For` header, once any application proxy IP addresses have first been excluded.
+If you need to strictly identify unique client IP addresses, you'll need to first configure the number of application proxies that the API runs behind by setting the `NUM_PROXIES` setting. This setting should be an integer of zero or more. If set to non-zero then the client IP will be identified as being the last IP address in the `X-Forwarded-For` header, once any application proxy IP addresses have first been excluded. If set to zero, then the `Remote-Addr` header will always be used as the identifying IP address.
It is important to understand that if you configure the `NUM_PROXIES` setting, then all clients behind a unique [NAT'd](http://en.wikipedia.org/wiki/Network_address_translation) gateway will be treated as a single client.
-Further context on how the `X-Forwarded-For` header works, and identifier a remote client IP can be [found here][identifing-clients].
+Further context on how the `X-Forwarded-For` header works, and identifing a remote client IP can be [found here][identifing-clients].
## Setting up the cache
--
cgit v1.2.3
From a1d7aa8f712b659f9d8302a2d2a098d2538e6c89 Mon Sep 17 00:00:00 2001
From: Paul Melnikow
Date: Thu, 2 Jan 2014 17:44:47 -0500
Subject: Allow viewset to specify lookup value regex for routing
This patch allows a viewset to define a pattern for its lookup field, which the router will honor. Without this patch, any characters are allowed in the lookup field, and overriding this behavior requires subclassing router and copying and pasting the implementation of get_lookup_regex.
It's possible it would be better to remove this functionality from the routers and simply expose a parameter to get_lookup_regex which allows overriding the lookup_regex. That way the viewset config logic could be in the a subclass, which could invoke the super method directly.
I'm using this now for PostgreSQL UUID fields using https://github.com/dcramer/django-uuidfield . Without this patch, that field passes the lookup string to the database driver, which raises a DataError to complain about the invalid UUID. It's possible the field ought to signal this error in a different way, which could obviate the need to specify a pattern.
---
docs/api-guide/routers.md | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'docs')
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 846ac9f9..f3beabdd 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -83,6 +83,12 @@ This behavior can be modified by setting the `trailing_slash` argument to `False
Trailing slashes are conventional in Django, but are not used by default in some other frameworks such as Rails. Which style you choose to use is largely a matter of preference, although some javascript frameworks may expect a particular routing style.
+With `trailing_slash` set to True, the router will match lookup values containing any characters except slashes and dots. When set to False, dots are allowed. To restrict the lookup pattern, set the `lookup_field_regex` attribute on the viewset. For example, you can limit the lookup to valid UUIDs:
+
+ class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
+ lookup_field = 'my_model_id'
+ lookup_value_regex = '[0-9a-f]{32}'
+
## 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.
--
cgit v1.2.3
From 3cd15fb1713dfc49e1bf1fd48045ca3ae5654e18 Mon Sep 17 00:00:00 2001
From: Paul Melnikow
Date: Sat, 4 Jan 2014 16:57:50 -0500
Subject: Router: Do not automatically adjust lookup_regex when trailing_slash
is True
BREAKING CHANGE
When trailing_slash is set to True, the router no longer will adjust the lookup regex to allow it to include periods. To simulate the old behavior, the programmer should specify `lookup_regex = '[^/]+'` on the viewset.
https://github.com/tomchristie/django-rest-framework/pull/1328#issuecomment-31517099
---
docs/api-guide/routers.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index f3beabdd..6b4ae6db 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -83,7 +83,7 @@ This behavior can be modified by setting the `trailing_slash` argument to `False
Trailing slashes are conventional in Django, but are not used by default in some other frameworks such as Rails. Which style you choose to use is largely a matter of preference, although some javascript frameworks may expect a particular routing style.
-With `trailing_slash` set to True, the router will match lookup values containing any characters except slashes and dots. When set to False, dots are allowed. To restrict the lookup pattern, set the `lookup_field_regex` attribute on the viewset. For example, you can limit the lookup to valid UUIDs:
+The router will match lookup values containing any characters except slashes and period characters. For a more restrictive (or lenient) lookup pattern, set the `lookup_field_regex` attribute on the viewset. For example, you can limit the lookup to valid UUIDs:
class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
lookup_field = 'my_model_id'
--
cgit v1.2.3
From 899381575a6038f550a064261ed5c6ba0655211b Mon Sep 17 00:00:00 2001
From: Paul Melnikow
Date: Sat, 4 Jan 2014 17:03:01 -0500
Subject: Fix a typo
---
docs/api-guide/routers.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 6b4ae6db..249e99a4 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -83,7 +83,7 @@ This behavior can be modified by setting the `trailing_slash` argument to `False
Trailing slashes are conventional in Django, but are not used by default in some other frameworks such as Rails. Which style you choose to use is largely a matter of preference, although some javascript frameworks may expect a particular routing style.
-The router will match lookup values containing any characters except slashes and period characters. For a more restrictive (or lenient) lookup pattern, set the `lookup_field_regex` attribute on the viewset. For example, you can limit the lookup to valid UUIDs:
+The router will match lookup values containing any characters except slashes and period characters. For a more restrictive (or lenient) lookup pattern, set the `lookup_value_regex` attribute on the viewset. For example, you can limit the lookup to valid UUIDs:
class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
lookup_field = 'my_model_id'
--
cgit v1.2.3
From 6e622d644c9b55b905e24497f0fb818d557fd970 Mon Sep 17 00:00:00 2001
From: Yuri Prezument
Date: Sun, 5 Jan 2014 15:58:46 +0200
Subject: CharField - add allow_null argument
---
docs/api-guide/fields.md | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index e05c0306..83825350 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -157,23 +157,24 @@ Corresponds to `django.db.models.fields.BooleanField`.
## CharField
A text representation, optionally validates the text to be shorter than `max_length` and longer than `min_length`.
+If `allow_none` is `False` (default), `None` values will be converted to an empty string.
Corresponds to `django.db.models.fields.CharField`
or `django.db.models.fields.TextField`.
-**Signature:** `CharField(max_length=None, min_length=None)`
+**Signature:** `CharField(max_length=None, min_length=None, allow_none=False)`
## URLField
Corresponds to `django.db.models.fields.URLField`. Uses Django's `django.core.validators.URLValidator` for validation.
-**Signature:** `CharField(max_length=200, min_length=None)`
+**Signature:** `CharField(max_length=200, min_length=None, allow_none=False)`
## SlugField
Corresponds to `django.db.models.fields.SlugField`.
-**Signature:** `CharField(max_length=50, min_length=None)`
+**Signature:** `CharField(max_length=50, min_length=None, allow_none=False)`
## ChoiceField
--
cgit v1.2.3
From a90796c0f0d9db1a7d9bfaca8fbdfed22435c628 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 13 Jan 2014 09:56:57 +0000
Subject: Track changes that need noting in 2.4 announcement
---
docs/topics/2.4-accouncement.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/topics/2.4-accouncement.md b/docs/topics/2.4-accouncement.md
index a5425d54..0cf50ce9 100644
--- a/docs/topics/2.4-accouncement.md
+++ b/docs/topics/2.4-accouncement.md
@@ -1,4 +1,4 @@
* Writable nested serializers.
* List/detail routes.
* 1.3 Support dropped, install six for <=1.4.?.
-* Note title ordering changed
\ No newline at end of file
+* `allow_none` for char fields
--
cgit v1.2.3
From 2911cd64ad67ba193e3d37322ee71692cb482623 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 13 Jan 2014 15:37:52 +0000
Subject: Minor tweaks to 'lookup_value_regex' work
---
docs/topics/2.4-accouncement.md | 1 +
1 file changed, 1 insertion(+)
(limited to 'docs')
diff --git a/docs/topics/2.4-accouncement.md b/docs/topics/2.4-accouncement.md
index 0cf50ce9..91472b9c 100644
--- a/docs/topics/2.4-accouncement.md
+++ b/docs/topics/2.4-accouncement.md
@@ -2,3 +2,4 @@
* List/detail routes.
* 1.3 Support dropped, install six for <=1.4.?.
* `allow_none` for char fields
+* `trailing_slash = True` --> `[^/]`, `trailing_slash = False` --> `[^/.]`, becomes simply `[^/]` and `lookup_value_regex` is added.
--
cgit v1.2.3
From 971578ca345c3d3bae7fd93b87c41d43483b6f05 Mon Sep 17 00:00:00 2001
From: Andreas Pelme
Date: Sun, 2 Mar 2014 12:40:30 +0100
Subject: Support for running the test suite with py.test
* Get rid of runtests.py
* Moved test code from rest_framework/tests and rest_framework/runtests to tests
* Invoke py.test from setup.py
* Invoke py.test from Travis
* Invoke py.test from tox
* Changed setUpClass to be just plain setUp in test_permissions.py
* Updated contribution guideline to show how to invoke py.test
---
docs/index.md | 16 +++-------------
docs/topics/contributing.md | 2 +-
2 files changed, 4 insertions(+), 14 deletions(-)
(limited to 'docs')
diff --git a/docs/index.md b/docs/index.md
index 2a4ad885..9ad647ac 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -206,19 +206,9 @@ General guides to using REST framework.
## Development
-If you want to work on REST framework itself, clone the repository, then...
-
-Build the docs:
-
- ./mkdocs.py
-
-Run the tests:
-
- ./rest_framework/runtests/runtests.py
-
-To run the tests against all supported configurations, first install [the tox testing tool][tox] globally, using `pip install tox`, then simply run `tox`:
-
- tox
+See the [Contribution guidelines][contributing] for information on how to clone
+the repository, run the test suite and contribute changes back to REST
+Framework.
## Support
diff --git a/docs/topics/contributing.md b/docs/topics/contributing.md
index 5a5d1a80..09cc00b3 100644
--- a/docs/topics/contributing.md
+++ b/docs/topics/contributing.md
@@ -65,7 +65,7 @@ To run the tests, clone the repository, and then:
pip install -r optionals.txt
# Run the tests
- rest_framework/runtests/runtests.py
+ py.test
You can also use the excellent `[tox][tox]` testing tool to run the tests against all supported versions of Python and Django. Install `tox` globally, and then simply run:
--
cgit v1.2.3
From 15c2c58b43a00ec29af99e0478b70eea57560fce Mon Sep 17 00:00:00 2001
From: Xavier Ordoquy
Date: Thu, 1 May 2014 08:43:49 +0200
Subject: Updated the release-notes.
---
docs/topics/release-notes.md | 1 +
1 file changed, 1 insertion(+)
(limited to 'docs')
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index d6256b38..fd5c7029 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -40,6 +40,7 @@ You can determine your currently installed version using `pip freeze`:
### 2.4.0
+* Use py.test
* `@detail_route` and `@list_route` decorators replace `@action` and `@link`.
* `six` no longer bundled. For Django <= 1.4.1, install `six` package.
* Support customizable view name and description functions, using the `VIEW_NAME_FUNCTION` and `VIEW_DESCRIPTION_FUNCTION` settings.
--
cgit v1.2.3
From 3f727ce738776838d8420450ce28485954fbb097 Mon Sep 17 00:00:00 2001
From: Carlton Gibson
Date: Tue, 24 Jun 2014 09:02:44 +0200
Subject: Added (first pass) notes to docs & release notes. Backed out
`SOUTH_MIGRATION_MODULES` setting from `rest_framework.settings`
---
docs/api-guide/authentication.md | 24 ++++++++++++++++++++++--
docs/topics/release-notes.md | 16 ++++++++++++----
2 files changed, 34 insertions(+), 6 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index 88a7a011..0bddd0d0 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -126,7 +126,13 @@ To use the `TokenAuthentication` scheme, include `rest_framework.authtoken` in y
'rest_framework.authtoken'
)
-Make sure to run `manage.py syncdb` after changing your settings. The `authtoken` database tables are managed by south (see [Schema migrations](#schema-migrations) below).
+
+---
+
+**Note:** Make sure to run `manage.py syncdb` after changing your settings. Both Django native (from v1.7) and South migrations for the `authtoken` database tables are provided. See [Schema migrations](#schema-migrations) below.
+
+---
+
You'll also need to create tokens for your users.
@@ -198,7 +204,21 @@ Note that the default `obtain_auth_token` view explicitly uses JSON requests and
#### Schema migrations
-The `rest_framework.authtoken` app includes a south migration that will create the authtoken table.
+The `rest_framework.authtoken` app includes both a Django native migration (for Django versions >1.7) and a south migration that will create the authtoken table.
+
+----
+
+**Note** By default both Django (>1.7) and South will look for a module named `migrations`. To avoid a collision here, in order to use South you **must** provide the `SOUTH_MIGRATION_MODULES` option in your `settings.py`:
+
+
+ SOUTH_MIGRATION_MODULES = {
+ 'authtoken': 'rest_framework.authtoken.south_migrations',
+ }
+
+This tells South to look in the `south_migrations` module for the `authtoken` app.
+
+----
+
If you're using a [custom user model][custom-user-model] you'll need to make sure that any initial migration that creates the user table runs before the authtoken table is created.
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 335497ee..5722d45b 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -43,6 +43,14 @@ You can determine your currently installed version using `pip freeze`:
### 2.3.x
**Date**: April 2014
+* Added compatibility with Django 1.7's native migrations.
+
+ **IMPORTANT**: In order to continue to use south with Django <1.7 you **must** provide
+ the `SOUTH_MIGRATION_MODULES` option in your `settings.py`:
+
+ SOUTH_MIGRATION_MODULES = {
+ 'authtoken': 'rest_framework.authtoken.south_migrations',
+ }
* Fix nested serializers linked through a backward foreign key relation
* Fix bad links for the `BrowsableAPIRenderer` with `YAMLRenderer`
@@ -165,9 +173,9 @@ You can determine your currently installed version using `pip freeze`:
* Added `trailing_slash` option to routers.
* Include support for `HttpStreamingResponse`.
* Support wider range of default serializer validation when used with custom model fields.
-* UTF-8 Support for browsable API descriptions.
+* UTF-8 Support for browsable API descriptions.
* OAuth2 provider uses timezone aware datetimes when supported.
-* Bugfix: Return error correctly when OAuth non-existent consumer occurs.
+* Bugfix: Return error correctly when OAuth non-existent consumer occurs.
* Bugfix: Allow `FileUploadParser` to correctly filename if provided as URL kwarg.
* Bugfix: Fix `ScopedRateThrottle`.
@@ -208,7 +216,7 @@ You can determine your currently installed version using `pip freeze`:
* Added SearchFilter
* Added OrderingFilter
* Added GenericViewSet
-* Bugfix: Multiple `@action` and `@link` methods now allowed on viewsets.
+* Bugfix: Multiple `@action` and `@link` methods now allowed on viewsets.
* Bugfix: Fix API Root view issue with DjangoModelPermissions
### 2.3.2
@@ -261,7 +269,7 @@ You can determine your currently installed version using `pip freeze`:
* Long HTTP headers in browsable API are broken in multiple lines when possible.
* Bugfix: Fix regression with DjangoFilterBackend not worthing correctly with single object views.
* Bugfix: OAuth should fail hard when invalid token used.
-* Bugfix: Fix serializer potentially returning `None` object for models that define `__bool__` or `__len__`.
+* Bugfix: Fix serializer potentially returning `None` object for models that define `__bool__` or `__len__`.
### 2.2.5
--
cgit v1.2.3
From ae2ab496c2fa42ed60d325df4579b1ba38d3bfb5 Mon Sep 17 00:00:00 2001
From: Carlton Gibson
Date: Mon, 18 Aug 2014 13:48:46 +0200
Subject: Updated docs for South v1.0
---
docs/api-guide/authentication.md | 11 ++---------
docs/topics/release-notes.md | 7 ++-----
2 files changed, 4 insertions(+), 14 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index ad6257dd..ee59b375 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -204,18 +204,11 @@ Note that the default `obtain_auth_token` view explicitly uses JSON requests and
#### Schema migrations
-The `rest_framework.authtoken` app includes both a Django native migration (for Django versions >1.7) and a south migration that will create the authtoken table.
+The `rest_framework.authtoken` app includes both Django native migrations (for Django versions >1.7) and South migrations (for Django versions <1.7) that will create the authtoken table.
----
-**Note** By default both Django (>1.7) and South will look for a module named `migrations`. To avoid a collision here, in order to use South you **must** provide the `SOUTH_MIGRATION_MODULES` option in your `settings.py`:
-
-
- SOUTH_MIGRATION_MODULES = {
- 'authtoken': 'rest_framework.authtoken.south_migrations',
- }
-
-This tells South to look in the `south_migrations` module for the `authtoken` app.
+**Note**: From REST Framework v2.4.0 using South with Django <1.7 requires upgrading South v1.0+
----
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 9c87c6c1..b0e5b198 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -42,12 +42,9 @@ You can determine your currently installed version using `pip freeze`:
* Added compatibility with Django 1.7's native migrations.
- **IMPORTANT**: In order to continue to use south with Django <1.7 you **must** provide
- the `SOUTH_MIGRATION_MODULES` option in your `settings.py`:
+ **IMPORTANT**: In order to continue to use South with Django <1.7 you **must** upgrade to
+ South v1.0.
- SOUTH_MIGRATION_MODULES = {
- 'authtoken': 'rest_framework.authtoken.south_migrations',
- }
* Use py.test
* `@detail_route` and `@list_route` decorators replace `@action` and `@link`.
* `six` no longer bundled. For Django <= 1.4.1, install `six` package.
--
cgit v1.2.3
From db4426fc35a92d2b0e263fd8a5702203cb3e06ed Mon Sep 17 00:00:00 2001
From: Carlton Gibson
Date: Mon, 18 Aug 2014 13:52:57 +0200
Subject: Alter other reference to migrations.
---
docs/api-guide/authentication.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index ee59b375..bc2ca4b6 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -129,7 +129,7 @@ To use the `TokenAuthentication` scheme you'll need to [configure the authentica
---
-**Note:** Make sure to run `manage.py syncdb` after changing your settings. Both Django native (from v1.7) and South migrations for the `authtoken` database tables are provided. See [Schema migrations](#schema-migrations) below.
+**Note:** Make sure to run `manage.py syncdb` after changing your settings. The 'rest_framework.authtoken' provides both Django (from v1.7) and South database migrations. See [Schema migrations](#schema-migrations) below.
---
--
cgit v1.2.3
From 556948661acc4bf038ecdd0cb17b1e19f2080061 Mon Sep 17 00:00:00 2001
From: Carlton Gibson
Date: Mon, 18 Aug 2014 13:54:46 +0200
Subject: Improve wording.
---
docs/api-guide/authentication.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index bc2ca4b6..343466ee 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -129,7 +129,7 @@ To use the `TokenAuthentication` scheme you'll need to [configure the authentica
---
-**Note:** Make sure to run `manage.py syncdb` after changing your settings. The 'rest_framework.authtoken' provides both Django (from v1.7) and South database migrations. See [Schema migrations](#schema-migrations) below.
+**Note:** Make sure to run `manage.py syncdb` after changing your settings. The `rest_framework.authtoken` app provides both Django (from v1.7) and South database migrations. See [Schema migrations](#schema-migrations) below.
---
--
cgit v1.2.3
From 00c0dfc66fd2426a63e6eec498395740b2c3e63b Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Tue, 19 Aug 2014 16:29:05 +0100
Subject: Documentation on runtests.py
---
docs/topics/contributing.md | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/topics/contributing.md b/docs/topics/contributing.md
index d33843e1..3400bc8f 100644
--- a/docs/topics/contributing.md
+++ b/docs/topics/contributing.md
@@ -62,10 +62,44 @@ To run the tests, clone the repository, and then:
virtualenv env
source env/bin/activate
pip install -r requirements.txt
- pip install -r optionals.txt
+ pip install -r requirements-test.txt
# Run the tests
- py.test
+ ./runtests.py
+
+### Test options
+
+Run using a more concise output style.
+
+ ./runtests -q
+
+Run the tests using a more concise output style, no coverage, no flake8.
+
+ ./runtests --fast
+
+Don't run the flake8 code linting.
+
+ ./runtests --nolint
+
+Only run the flake8 code linting, don't run the tests.
+
+ ./runtests --lintonly
+
+Run the tests for a given test case.
+
+ ./runtests MyTestCase
+
+Run the tests for a given test method.
+
+ ./runtests MyTestCase.test_this_method
+
+Shorter form to run the tests for a given test method.
+
+ ./runtests test_this_method
+
+Note: The test case and test method matching is fuzzy and will sometimes run other tests that contain a partial string match to the given command line input.
+
+### Running against multiple environments
You can also use the excellent [tox][tox] testing tool to run the tests against all supported versions of Python and Django. Install `tox` globally, and then simply run:
--
cgit v1.2.3
From 63d02dbea855a060ec4cdb194497188e2f40cb66 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Tue, 19 Aug 2014 17:06:55 +0100
Subject: Drop six from compat. 1.4.2 is now the lowest supported version.
---
docs/index.md | 2 +-
docs/topics/2.4-accouncement.md | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
(limited to 'docs')
diff --git a/docs/index.md b/docs/index.md
index 6abc4f04..83e30a69 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -50,7 +50,7 @@ Some reasons you might want to use REST framework:
REST framework requires the following:
* Python (2.6.5+, 2.7, 3.2, 3.3)
-* Django (1.3, 1.4, 1.5, 1.6)
+* Django (1.4.2+, 1.5, 1.6, 1.7)
The following packages are optional:
diff --git a/docs/topics/2.4-accouncement.md b/docs/topics/2.4-accouncement.md
index 91472b9c..cdc99bd5 100644
--- a/docs/topics/2.4-accouncement.md
+++ b/docs/topics/2.4-accouncement.md
@@ -1,4 +1,3 @@
-* Writable nested serializers.
* List/detail routes.
* 1.3 Support dropped, install six for <=1.4.?.
* `allow_none` for char fields
--
cgit v1.2.3
From 0c65e028b604490d498e43083fc3b46da05144fe Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Tue, 19 Aug 2014 23:25:12 +0100
Subject: Release notes
---
docs/api-guide/viewsets.md | 2 +-
docs/topics/2.4-accouncement.md | 111 +++++++++++++++++++++++++++++++++++++++-
docs/topics/release-notes.md | 21 +++++---
3 files changed, 125 insertions(+), 9 deletions(-)
(limited to 'docs')
diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md
index b32f5a80..9030e3ee 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -146,7 +146,7 @@ The decorators can additionally take extra arguments that will be set for the ro
def set_password(self, request, pk=None):
...
-The `@action` decorator will route `POST` requests by default, but may also accept other HTTP methods, by using the `methods` argument. For example:
+Theses decorators will route `GET` requests by default, but may also accept other HTTP methods, by using the `methods` argument. For example:
@detail_route(methods=['post', 'delete'])
def unset_password(self, request, pk=None):
diff --git a/docs/topics/2.4-accouncement.md b/docs/topics/2.4-accouncement.md
index cdc99bd5..709a5c96 100644
--- a/docs/topics/2.4-accouncement.md
+++ b/docs/topics/2.4-accouncement.md
@@ -1,4 +1,111 @@
-* List/detail routes.
-* 1.3 Support dropped, install six for <=1.4.?.
+# REST framework 2.4 announcement
+
+The 2.4 release is largely an intermediate step, tying up some outstanding issues prior to the 3.x series.
+
+## Version requirements
+
+Support for Django 1.3 has been dropped.
+The lowest supported version of Django is now 1.4.2.
+
+The current plan is for REST framework to remain in lockstep with [Django's long-term support policy][lts-releases].
+
+## Django 1.7 support
+
+The optional authtoken application now includes support for *both* Django 1.7 schema migrations, *and* for old-style `south` migrations.
+
+**If you are using authtoken, and you want to continue using `south`, you must upgrade your `south` package to version 1.0.**
+
+## Updated test runner
+
+We now have a new test runner for developing against the project,, that uses the excellent [py.test](http://pytest.org) library.
+
+To use it make sure you have first installed the test requirements.
+
+ pip install -r requirements-test.txt
+
+Then run the `runtests.py` script.
+
+ ./runtests.py
+
+The new test runner also includes [flake8](https://flake8.readthedocs.org) code linting, which should help keep our coding style consistent.
+
+#### Test runner flags
+
+Run using a more concise output style.
+
+ ./runtests -q
+
+Run the tests using a more concise output style, no coverage, no flake8.
+
+ ./runtests --fast
+
+Don't run the flake8 code linting.
+
+ ./runtests --nolint
+
+Only run the flake8 code linting, don't run the tests.
+
+ ./runtests --lintonly
+
+Run the tests for a given test case.
+
+ ./runtests MyTestCase
+
+Run the tests for a given test method.
+
+ ./runtests MyTestCase.test_this_method
+
+Shorter form to run the tests for a given test method.
+
+ ./runtests test_this_method
+
+Note: The test case and test method matching is fuzzy and will sometimes run other tests that contain a partial string match to the given command line input.
+
+## Improved viewset routing
+
+The `@action` and `@link` decorators were inflexible in that they only allowed additional routes to be added against instance style URLs, not against list style URLs.
+
+The `@action` and `@link` decorators have now been moved to pending deprecation, and the `@list_route` and `@detail_route` decroators have been introduced.
+
+Here's an example of using the new decorators. Firstly we have a detail-type route named "set_password" that acts on a single instance, and takes a `pk` argument in the URL. Secondly we have a list-type route named "recent_users" that acts on a queryset, and does not take any arguments in the URL.
+
+ class UserViewSet(viewsets.ModelViewSet):
+ """
+ A viewset that provides the standard actions
+ """
+ queryset = User.objects.all()
+ serializer_class = UserSerializer
+
+ @detail_route(methods=['post'])
+ 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)
+
+ @list_route()
+ def recent_users(self, request):
+ recent_users = User.objects.all().order('-last_login')
+ page = self.paginate_queryset(recent_users)
+ serializer = self.get_pagination_serializer(page)
+ return Response(serializer.data)
+
+For more details, see the [viewsets](../api-guide/viewsets.md) documentation.
+
+## Other features
+
+## Deprecations
+
+## Labels and milestones
+
+TODO
+
* `allow_none` for char fields
* `trailing_slash = True` --> `[^/]`, `trailing_slash = False` --> `[^/.]`, becomes simply `[^/]` and `lookup_value_regex` is added.
+
+[lts-releases]: https://docs.djangoproject.com/en/dev/internals/release-process/#long-term-support-lts-releases
\ No newline at end of file
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index b0e5b198..a31be28f 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -38,26 +38,35 @@ You can determine your currently installed version using `pip freeze`:
---
+## 2.4.x series
+
### 2.4.0
-* Added compatibility with Django 1.7's native migrations.
+**Django version requirements**: The lowest supported version of Django is now 1.4.2.
- **IMPORTANT**: In order to continue to use South with Django <1.7 you **must** upgrade to
- South v1.0.
+**South version requirements**: This note applies to any users using the optional `authtoken` application, which includes an associated database migration. You must now *either* upgrade your `south` package to version 1.0, *or* instead use the built-in migration support available with Django 1.7.
-* Use py.test
+* Added compatibility with Django 1.7's database migration support.
+* New test runner, using `py.test`.
* `@detail_route` and `@list_route` decorators replace `@action` and `@link`.
-* `six` no longer bundled. For Django <= 1.4.1, install `six` package.
* Support customizable view name and description functions, using the `VIEW_NAME_FUNCTION` and `VIEW_DESCRIPTION_FUNCTION` settings.
* Added `NUM_PROXIES` setting for smarter client IP identification.
* Added `MAX_PAGINATE_BY` setting and `max_paginate_by` generic view attribute.
* Added `cache` attribute to throttles to allow overriding of default cache.
+* Added `lookup_value_regex` attribute to routers, to allow the URL argument matching to be constrainted by the user.
+* Added `allow_none` option to `CharField`.
+* Support Django's standard `status_code` class attribute on responses.
+* More intuitive behavior on the test client, as `client.logout()` now also removes any credentials that have been set.
* Bugfix: `?page_size=0` query parameter now falls back to default page size for view, instead of always turning pagination off.
+* Bugfix: Always uppercase `X-Http-Method-Override` methods.
+* Bugfix: Copy `filter_backends` list before returning it, in order to prevent view code from mutating the class attribute itself.
+* Bugfix: Set the `.action` attribute on viewsets when introspected by `OPTIONS` for testing permissions on the view.
+* Bugfix: Ensure `ValueError` raised during deserialization results in a error list rather than a single error. This is now consistent with other validation errors.
+---
## 2.3.x series
-
### 2.3.14
**Date**: 12th June 2014
--
cgit v1.2.3
From 874d2be83c612fb5e04aa6a28901c2afe4bf9d3b Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Wed, 20 Aug 2014 00:19:03 +0100
Subject: Release notes
---
docs/img/labels-and-milestones.png | Bin 0 -> 84026 bytes
docs/topics/2.4-accouncement.md | 48 ++++++++++++++++++++++++++++++++-----
2 files changed, 42 insertions(+), 6 deletions(-)
create mode 100644 docs/img/labels-and-milestones.png
(limited to 'docs')
diff --git a/docs/img/labels-and-milestones.png b/docs/img/labels-and-milestones.png
new file mode 100644
index 00000000..e7c829ad
Binary files /dev/null and b/docs/img/labels-and-milestones.png differ
diff --git a/docs/topics/2.4-accouncement.md b/docs/topics/2.4-accouncement.md
index 709a5c96..50484287 100644
--- a/docs/topics/2.4-accouncement.md
+++ b/docs/topics/2.4-accouncement.md
@@ -95,17 +95,53 @@ Here's an example of using the new decorators. Firstly we have a detail-type rou
serializer = self.get_pagination_serializer(page)
return Response(serializer.data)
-For more details, see the [viewsets](../api-guide/viewsets.md) documentation.
+For more details, see the [viewsets documentation](../api-guide/viewsets.md).
## Other features
-## Deprecations
+There are also a number of other features and bugfixes as [listed in the release notes][2-4-release-notes]. In particular these include:
+
+[Customizable view name and description functions][view-name-and-description-settings] for use with the browsable API, by using the `VIEW_NAME_FUNCTION` and `VIEW_DESCRIPTION_FUNCTION` settings.
+
+Smarter [client IP identification for throttling][client-ip-identification], with the addition of the `NUM_PROXIES` setting.
+
+## Deprecations
+
+All API changes in 2.3 that previously raised `PendingDeprecationWarning` will now raise a `DeprecationWarning`, which is loud by default.
+
+All API changes in 2.3 that previously raised `DeprecationWarning` have now been removed entirely.
+
+Furter details on these deprecations is available in the [2.3 announcement][2-3-announcement].
## Labels and milestones
-TODO
+Although not strictly part of the 2.4 release it's also worth noting here that we've been working hard towards improving our triage process.
+
+The [labels that we use in GitHub][github-labels] have been cleaned up, and all existing tickets triaged. Any given ticket should have one and only one label, indicating its current state.
+
+We've also [started using milestones][github-milestones] in order to track tickets against particular releases.
+
+---
+
+
+
+**Above**: *Overview of our current use of labels and milestones in GitHub.*
+
+---
+
+We hope both of these changes will help make the management process more clear and obvious and help keep tickets well-organised and relevant.
+
+## Next steps
+
+The next planned release will be 3.0, featuring an improved and simplified serializer implementation.
-* `allow_none` for char fields
-* `trailing_slash = True` --> `[^/]`, `trailing_slash = False` --> `[^/.]`, becomes simply `[^/]` and `lookup_value_regex` is added.
+Once again, many thanks to all the generous [backers and sponsors][kickstarter-sponsors] who've helped make this possible!
-[lts-releases]: https://docs.djangoproject.com/en/dev/internals/release-process/#long-term-support-lts-releases
\ No newline at end of file
+[lts-releases]: https://docs.djangoproject.com/en/dev/internals/release-process/#long-term-support-lts-releases
+[2-4-release-notes]: ./topics/release-notes/#240
+[view-name-and-description-settings]: ../api-guide/settings/#view-names-and-descriptions
+[client-ip-identification]: ../api-guide/throttling/#how-clients-are-identified
+[2-3-announcement]: ./topics/2.3-announcement
+[github-labels]: https://github.com/tomchristie/django-rest-framework/issues
+[github-milestones]: https://github.com/tomchristie/django-rest-framework/milestones
+[kickstarter-sponsors]: ./topics/kickstarter-announcement/#sponsors
--
cgit v1.2.3