From bda25479aa7e73c90bc77b7c7219eaa411af138e Mon Sep 17 00:00:00 2001
From: Mark Aaron Shirley
Date: Wed, 10 Apr 2013 08:44:54 -0700
Subject: Update docs with allow_add_remove
---
docs/api-guide/serializers.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index 42e81cad..aeb33916 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -244,15 +244,15 @@ This allows you to write views that update or create multiple items when a `PUT`
Bulk updates will update any instances that already exist, and create new instances for data items that do not have a corresponding instance.
-When performing a bulk update you may want any items that are not present in the incoming data to be deleted. To do so, pass `allow_delete=True` to the serializer.
+When performing a bulk update you may want any items that are not present in the incoming data to be deleted. To do so, pass `allow_add_remove=True` to the serializer.
- serializer = BookSerializer(queryset, data=data, many=True, allow_delete=True)
+ serializer = BookSerializer(queryset, data=data, many=True, allow_add_remove=True)
serializer.is_valid()
# True
serializer.save() # `.save()` will be called on each updated or newly created instance.
# `.delete()` will be called on any other items in the `queryset`.
-Passing `allow_delete=True` ensures that any update operations will completely overwrite the existing queryset, rather than simply updating any objects found in the incoming data.
+Passing `allow_add_remove=True` ensures that any update operations will completely overwrite the existing queryset, rather than simply updating any objects found in the incoming data.
#### How identity is determined when performing bulk updates
--
cgit v1.2.3
From 7815811fe3047b5110e6993ecd72349f6f232232 Mon Sep 17 00:00:00 2001
From: Mark Aaron Shirley
Date: Sun, 14 Jul 2013 18:13:37 -0700
Subject: Update nested serialization docs
---
docs/api-guide/relations.md | 2 --
docs/api-guide/serializers.md | 17 ++++++++++-------
2 files changed, 10 insertions(+), 9 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md
index 50c9bc54..21942eef 100644
--- a/docs/api-guide/relations.md
+++ b/docs/api-guide/relations.md
@@ -213,8 +213,6 @@ Nested relationships can be expressed by using serializers as fields.
If the field is used to represent a to-many relationship, you should add the `many=True` flag to the serializer field.
-Note that nested relationships are currently read-only. For read-write relationships, you should use a flat relational style.
-
## Example
For example, the following serializer:
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index d9c23580..23c99942 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -177,7 +177,7 @@ If a nested representation may optionally accept the `None` value you should pas
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
-Similarly if a nested representation should be a list of items, you should the `many=True` flag to the nested serialized.
+Similarly if a nested representation should be a list of items, you should pass the `many=True` flag to the nested serialized.
class CommentSerializer(serializers.Serializer):
user = UserSerializer(required=False)
@@ -185,11 +185,13 @@ Similarly if a nested representation should be a list of items, you should the `
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
----
-
-**Note**: Nested serializers are only suitable for read-only representations, as there are cases where they would have ambiguous or non-obvious behavior if used when updating instances. For read-write representations you should always use a flat representation, by using one of the `RelatedField` subclasses.
+Validation of nested objects will work the same as before. Errors with nested objects will be nested under the field name of the nested object.
----
+ serializer = CommentSerializer(comment, data={'user': {'email': 'foobar', 'user': 'doe'}, 'content': 'baz'})
+ serializer.is_valid()
+ # False
+ serializer.errors
+ # {'user': {'email': [u'Enter a valid e-mail address.']}, 'created': [u'This field is required.']}
## Dealing with multiple objects
@@ -293,8 +295,7 @@ You can provide arbitrary additional context by passing a `context` argument whe
The context dictionary can be used within any serializer field logic, such as a custom `.to_native()` method, by accessing the `self.context` attribute.
----
-
+-
# ModelSerializer
Often you'll want serializer classes that map closely to model definitions.
@@ -331,6 +332,8 @@ The default `ModelSerializer` uses primary keys for relationships, but you can a
The `depth` option should be set to an integer value that indicates the depth of relationships that should be traversed before reverting to a flat representation.
+If you want to customize the way the serialization is done (e.g. using `allow_add_remove`) you'll need to define the field yourself.
+
## Specifying which fields should be read-only
You may wish to specify multiple fields as read-only. Instead of adding each field explicitly with the `read_only=True` attribute, you may use the `read_only_fields` Meta option, like so:
--
cgit v1.2.3
From b5dc6b61131cc36b0540133a28613c06e7f4e26a Mon Sep 17 00:00:00 2001
From: Mark Aaron Shirley
Date: Sun, 14 Jul 2013 18:18:39 -0700
Subject: Fix docs typo
---
docs/api-guide/serializers.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index 23c99942..022853ca 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -187,7 +187,7 @@ Similarly if a nested representation should be a list of items, you should pass
Validation of nested objects will work the same as before. Errors with nested objects will be nested under the field name of the nested object.
- serializer = CommentSerializer(comment, data={'user': {'email': 'foobar', 'user': 'doe'}, 'content': 'baz'})
+ serializer = CommentSerializer(comment, data={'user': {'email': 'foobar', 'username': 'doe'}, 'content': 'baz'})
serializer.is_valid()
# False
serializer.errors
--
cgit v1.2.3
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/api-guide')
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/api-guide')
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/api-guide')
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 ++++++++--------
2 files changed, 16 insertions(+), 16 deletions(-)
(limited to 'docs/api-guide')
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):
...
---
--
cgit v1.2.3
From 1a4ff1567ea4231cde9a2f23725550a754f3f54c Mon Sep 17 00:00:00 2001
From: James Rutherford
Date: Mon, 29 Jul 2013 10:16:15 +0100
Subject: Updated authtoken docs to mention south migrations
---
docs/api-guide/authentication.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index ee1282b5..fd6bfb56 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -121,7 +121,7 @@ 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.
+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).
You'll also need to create tokens for your users.
--
cgit v1.2.3
From 195b1af7ba34b833fc17f5693d7fbd9c8e7cce78 Mon Sep 17 00:00:00 2001
From: James Rutherford
Date: Mon, 29 Jul 2013 10:16:51 +0100
Subject: Minor typo fix
---
docs/api-guide/authentication.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index fd6bfb56..b1ab4622 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -203,7 +203,7 @@ You can do so by inserting a `needed_by` attribute in your user migration:
For more details, see the [south documentation on dependencies][south-dependencies].
-Also not that if you're using a `post_save` signal to create tokens, then the first time you create the database tables, you'll need to ensure any migrations are run prior to creating any superusers. For example:
+Also note that if you're using a `post_save` signal to create tokens, then the first time you create the database tables, you'll need to ensure any migrations are run prior to creating any superusers. For example:
python manage.py syncdb --noinput # Won't create a superuser just yet, due to `--noinput`.
python manage.py migrate
--
cgit v1.2.3
From 294d957361c78cdafcef60f915738ed0e533327c Mon Sep 17 00:00:00 2001
From: Stephan Groß
Date: Wed, 31 Jul 2013 20:14:49 +0200
Subject: Add drf-any-permission docs entry
---
docs/api-guide/permissions.md | 11 +++++++++++
1 file changed, 11 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index 2c0a055c..57636bc6 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -188,6 +188,16 @@ Note that the generic views will check the appropriate object level permissions,
Also note that the generic views will only check the object-level permissions for views that retrieve a single model instance. If you require object-level filtering of list views, you'll need to filter the queryset separately. See the [filtering documentation][filtering] for more details.
+---
+
+# Third party packages
+
+The following third party packages are also available.
+
+## DRF Any Permissions
+
+The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to the REST framework. Only one of the given permissions have to be true in order to get access to the view.
+
[cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html
[authentication]: authentication.md
[throttling]: throttling.md
@@ -197,3 +207,4 @@ Also note that the generic views will only check the object-level permissions fo
[django-oauth2-provider]: https://github.com/caffeinehit/django-oauth2-provider
[2.2-announcement]: ../topics/2.2-announcement.md
[filtering]: filtering.md
+[drf-any-permissions]: https://github.com/kevin-brown/drf-any-permissions
--
cgit v1.2.3
From e61210399154723f342ab9295c938bf72c8da7a6 Mon Sep 17 00:00:00 2001
From: Stephan Groß
Date: Wed, 31 Jul 2013 20:25:28 +0200
Subject: Fix typo
---
docs/api-guide/permissions.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index 57636bc6..5597886d 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -196,7 +196,7 @@ The following third party packages are also available.
## DRF Any Permissions
-The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to the REST framework. Only one of the given permissions have to be true in order to get access to the view.
+The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to the REST framework. Only one of the given permissions has to be true in order to get access to the view.
[cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html
[authentication]: authentication.md
--
cgit v1.2.3
From 3802442c89a722da7e48210d315856b5993fcdbe Mon Sep 17 00:00:00 2001
From: Ricky Rosario
Date: Thu, 1 Aug 2013 17:02:16 -0400
Subject: Add missing comma to generic view example.
---
docs/api-guide/generic-views.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 67853ed0..32a4feef 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -40,7 +40,7 @@ For more complex cases you might also want to override various methods on the vi
For very simple cases you might want to pass through any class attributes using the `.as_view()` method. For example, your URLconf might include something the following entry.
- url(r'^/users/', ListCreateAPIView.as_view(model=User) name='user-list')
+ url(r'^/users/', ListCreateAPIView.as_view(model=User), name='user-list')
---
--
cgit v1.2.3
From 4ff1dc6a11ec9e1fd897cf2fdb74d57be7420515 Mon Sep 17 00:00:00 2001
From: James Summerfield
Date: Sat, 3 Aug 2013 10:23:39 +0100
Subject: Fixing typos in routers.md
---
docs/api-guide/routers.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 86582905..7f53f109 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -38,7 +38,7 @@ The example above would generate the following URL patterns:
### Extra link and actions
Any methods on the viewset decorated with `@link` or `@action` will also be routed.
-For example, a given method like this on the `UserViewSet` class:
+For example, given a method like this on the `UserViewSet` class:
@action(permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
@@ -66,7 +66,7 @@ This router includes routes for the standard set of `list`, `create`, `retrieve`
| POST | @action decorated method |
-By default the URLs created by `SimpleRouter` are appending with a trailing slash.
+By default the URLs created by `SimpleRouter` are appended with a trailing slash.
This behavior can be modified by setting the `trailing_slash` argument to `False` when instantiating the router. For example:
router = SimpleRouter(trailing_slash=False)
@@ -90,7 +90,7 @@ This router is similar to `SimpleRouter` as above, but additionally includes a d
| POST | @action 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.
+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.
router = DefaultRouter(trailing_slash=False)
@@ -139,7 +139,7 @@ The `SimpleRouter` class provides another example of setting the `.routes` attri
## Advanced custom routers
-If you want to provide totally custom behavior, you can override `BaseRouter` and override the `get_urls(self)` method. The method should insect the registered viewsets and return a list of URL patterns. The registered prefix, viewset and basename tuples may be inspected by accessing the `self.registry` attribute.
+If you want to provide totally custom behavior, you can override `BaseRouter` and override the `get_urls(self)` method. The method should inspect the registered viewsets and return a list of URL patterns. The registered prefix, viewset and basename tuples may be inspected by accessing the `self.registry` attribute.
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.
--
cgit v1.2.3
From 4d8d2340be4de905af3488dc721c7b94b1371ef0 Mon Sep 17 00:00:00 2001
From: Veronica Lynn
Date: Wed, 7 Aug 2013 14:00:06 -0400
Subject: Fixed typos in a bunch of docs
---
docs/api-guide/permissions.md | 2 +-
docs/api-guide/relations.md | 8 ++++----
docs/api-guide/renderers.md | 2 +-
docs/api-guide/responses.md | 4 ++--
docs/api-guide/reverse.md | 2 +-
docs/api-guide/routers.md | 2 +-
docs/api-guide/serializers.md | 6 +++---
docs/api-guide/settings.md | 4 ++--
docs/api-guide/testing.md | 2 +-
docs/api-guide/views.md | 2 +-
10 files changed, 17 insertions(+), 17 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index 5597886d..096ef369 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -147,7 +147,7 @@ If you need to test if a request is a read operation or a write operation, you s
**Note**: In versions 2.0 and 2.1, the signature for the permission checks always included an optional `obj` parameter, like so: `.has_permission(self, request, view, obj=None)`. The method would be called twice, first for the global permission checks, with no object supplied, and second for the object-level check when required.
-As of version 2.2 this signature has now been replaced with two separate method calls, which is more explict and obvious. The old style signature continues to work, but it's use will result in a `PendingDeprecationWarning`, which is silent by default. In 2.3 this will be escalated to a `DeprecationWarning`, and in 2.4 the old-style signature will be removed.
+As of version 2.2 this signature has now been replaced with two separate method calls, which is more explicit and obvious. The old style signature continues to work, but its use will result in a `PendingDeprecationWarning`, which is silent by default. In 2.3 this will be escalated to a `DeprecationWarning`, and in 2.4 the old-style signature will be removed.
For more details see the [2.2 release announcement][2.2-announcement].
diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md
index 50c9bc54..829a3c54 100644
--- a/docs/api-guide/relations.md
+++ b/docs/api-guide/relations.md
@@ -39,7 +39,7 @@ In order to explain the various types of relational fields, we'll use a couple o
## RelatedField
-`RelatedField` may be used to represent the target of the relationship using it's `__unicode__` method.
+`RelatedField` may be used to represent the target of the relationship using its `__unicode__` method.
For example, the following serializer.
@@ -71,7 +71,7 @@ This field is read only.
## PrimaryKeyRelatedField
-`PrimaryKeyRelatedField` may be used to represent the target of the relationship using it's primary key.
+`PrimaryKeyRelatedField` may be used to represent the target of the relationship using its primary key.
For example, the following serializer:
@@ -252,7 +252,7 @@ If you want to implement a read-write relational field, you must also implement
## Example
-For, example, we could define a relational field, to serialize a track to a custom string representation, using it's ordering, title, and duration.
+For, example, we could define a relational field, to serialize a track to a custom string representation, using its ordering, title, and duration.
import time
@@ -386,7 +386,7 @@ For more information see [the Django documentation on generic relations][generic
By default, relational fields that target a ``ManyToManyField`` with a
``through`` model specified are set to read-only.
-If you exlicitly specify a relational field pointing to a
+If you explicitly specify a relational field pointing to a
``ManyToManyField`` with a through model, be sure to set ``read_only``
to ``True``.
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index b434efe9..bb3d2015 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -241,7 +241,7 @@ This renderer is used for rendering HTML multipart form data. **It is not suita
To implement a custom renderer, you should override `BaseRenderer`, set the `.media_type` and `.format` properties, and implement the `.render(self, data, media_type=None, renderer_context=None)` method.
-The method should return a bytestring, which wil be used as the body of the HTTP response.
+The method should return a bytestring, which will be used as the body of the HTTP response.
The arguments passed to the `.render()` method are:
diff --git a/docs/api-guide/responses.md b/docs/api-guide/responses.md
index 399b7c23..5a42aa92 100644
--- a/docs/api-guide/responses.md
+++ b/docs/api-guide/responses.md
@@ -24,7 +24,7 @@ Unless you want to heavily customize REST framework for some reason, you should
Unlike regular `HttpResponse` objects, you do not instantiate `Response` objects with rendered content. Instead you pass in unrendered data, which may consist of any Python primitives.
-The renderers used by the `Response` class cannot natively handle complex datatypes such as Django model instances, so you need to serialize the data into primative datatypes before creating the `Response` object.
+The renderers used by the `Response` class cannot natively handle complex datatypes such as Django model instances, so you need to serialize the data into primitive datatypes before creating the `Response` object.
You can use REST framework's `Serializer` classes to perform this data serialization, or use your own custom serialization.
@@ -54,7 +54,7 @@ The rendered content of the response. The `.render()` method must have been cal
## .template_name
-The `template_name`, if supplied. Only required if `HTMLRenderer` or some other custom template renderer is the accepted renderer for the reponse.
+The `template_name`, if supplied. Only required if `HTMLRenderer` or some other custom template renderer is the accepted renderer for the response.
## .accepted_renderer
diff --git a/docs/api-guide/reverse.md b/docs/api-guide/reverse.md
index 19930dc3..94262366 100644
--- a/docs/api-guide/reverse.md
+++ b/docs/api-guide/reverse.md
@@ -17,7 +17,7 @@ The advantages of doing so are:
REST framework provides two utility functions to make it more simple to return absolute URIs from your Web API.
-There's no requirement for you to use them, but if you do then the self-describing API will be able to automatically hyperlink it's output for you, which makes browsing the API much easier.
+There's no requirement for you to use them, but if you do then the self-describing API will be able to automatically hyperlink its output for you, which makes browsing the API much easier.
## reverse
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 7f53f109..072a2e79 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -96,7 +96,7 @@ As with `SimpleRouter` the trailing slashes on the URL routes can be removed by
# Custom Routers
-Implementing a custom router isn't something you'd need to do very often, but it can be useful if you have specific requirements about how the your URLs for your API are strutured. Doing so allows you to encapsulate the URL structure in a reusable way that ensures you don't have to write your URL patterns explicitly for each new view.
+Implementing a custom router isn't something you'd need to do very often, but it can be useful if you have specific requirements about how the your URLs for your API are structured. Doing so allows you to encapsulate the URL structure in a reusable way that ensures you don't have to write your URL patterns explicitly for each new view.
The simplest way to implement a custom router is to subclass one of the existing router classes. The `.routes` attribute is used to template the URL patterns that will be mapped to each viewset. The `.routes` attribute is a list of `Route` named tuples.
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index a1f0853e..bbc8d019 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -403,7 +403,7 @@ You can change the field that is used for object lookups by setting the `lookup_
Not that the `lookup_field` will be used as the default on *all* hyperlinked fields, including both the URL identity, and any hyperlinked relationships.
-For more specfic requirements such as specifying a different lookup for each field, you'll want to set the fields on the serializer explicitly. For example:
+For more specific requirements such as specifying a different lookup for each field, you'll want to set the fields on the serializer explicitly. For example:
class AccountSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(
@@ -429,7 +429,7 @@ You can create customized subclasses of `ModelSerializer` or `HyperlinkedModelSe
Doing so should be considered advanced usage, and will only be needed if you have some particular serializer requirements that you often need to repeat.
-## Dynamically modifiying fields
+## Dynamically modifying fields
Once a serializer has been initialized, the dictionary of fields that are set on the serializer may be accessed using the `.fields` attribute. Accessing and modifying this attribute allows you to dynamically modify the serializer.
@@ -449,7 +449,7 @@ For example, if you wanted to be able to set which fields should be used by a se
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
- # Instatiate the superclass normally
+ # Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields:
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 7b114983..0be0eb24 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -28,7 +28,7 @@ you should use the `api_settings` object. For example.
print api_settings.DEFAULT_AUTHENTICATION_CLASSES
-The `api_settings` object will check for any user-defined settings, and otherwise fallback to the default values. Any setting that uses string import paths to refer to a class will automatically import and return the referenced class, instead of the string literal.
+The `api_settings` object will check for any user-defined settings, and otherwise fall back to the default values. Any setting that uses string import paths to refer to a class will automatically import and return the referenced class, instead of the string literal.
---
@@ -165,7 +165,7 @@ Default: `'multipart'`
The renderer classes that are supported when building test requests.
-The format of any of these renderer classes may be used when contructing a test request, for example: `client.post('/users', {'username': 'jamie'}, format='json')`
+The format of any of these renderer classes may be used when constructing a test request, for example: `client.post('/users', {'username': 'jamie'}, format='json')`
Default:
diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md
index 40b07763..92f8d54a 100644
--- a/docs/api-guide/testing.md
+++ b/docs/api-guide/testing.md
@@ -34,7 +34,7 @@ To support a wider set of request formats, or change the default format, [see th
#### Explicitly encoding the request body
-If you need to explictly encode the request body, you can do so by setting the `content_type` flag. For example:
+If you need to explicitly encode the request body, you can do so by setting the `content_type` flag. For example:
request = factory.post('/notes/', json.dumps({'title': 'new idea'}), content_type='application/json')
diff --git a/docs/api-guide/views.md b/docs/api-guide/views.md
index 683222d1..15581e09 100644
--- a/docs/api-guide/views.md
+++ b/docs/api-guide/views.md
@@ -110,7 +110,7 @@ You won't typically need to override this method.
### .finalize_response(self, request, response, \*args, **kwargs)
-Ensures that any `Response` object returned from the handler method will be rendered into the correct content type, as determined by the content negotation.
+Ensures that any `Response` object returned from the handler method will be rendered into the correct content type, as determined by the content negotiation.
You won't typically need to override this method.
--
cgit v1.2.3
From 13ca305b06a6d9bf982559640fa488f7ad31e2f8 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 16 Aug 2013 13:27:21 +0100
Subject: Tweak docs.
---
docs/api-guide/permissions.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index 096ef369..c6372f98 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -196,7 +196,7 @@ The following third party packages are also available.
## DRF Any Permissions
-The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to the REST framework. Only one of the given permissions has to be true in order to get access to the view.
+The [DRF Any Permissions][drf-any-permissions] packages provides a different permission behavior in contrast to REST framework. Instead of all specified permissions being required, only one of the given permissions has to be true in order to get access to the view.
[cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html
[authentication]: authentication.md
--
cgit v1.2.3
From 512067062419b736b65ca27bdb5663d863c775dd Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 19 Aug 2013 08:45:53 +0100
Subject: Document customizable view names/descriptions
---
docs/api-guide/settings.md | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 0be0eb24..fe7925a5 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -274,6 +274,40 @@ Default: `['iso-8601']`
---
+## View names and descriptions
+
+**The following settings are used to generate the view names and descriptions, as used in responses to `OPTIONS` requests, and as used in the browsable API.**
+
+#### VIEW_NAME_FUNCTION
+
+A string representing the function that should be used when generating view names.
+
+This should be a function with the following signature:
+
+ view_name(cls, suffix=None)
+
+* `cls`: The view class. Typically the name function would inspect the name of the class when generating a descriptive name, by accessing `cls.__name__`.
+* `suffix`: The optional suffix used when differentiating individual views in a viewset.
+
+Default: `'rest_framework.views.get_view_name'`
+
+#### VIEW_DESCRIPTION_FUNCTION
+
+A string representing the function that should be used when generating view descriptions.
+
+This setting can be changed to support markup styles other than the default markdown. For example, you can use it to support `rst` markup in your view docstrings being output in the browsable API.
+
+This should be a function with the following signature:
+
+ view_description(cls, html=False)
+
+* `cls`: The view class. Typically the description function would inspect the docstring of the class when generating a description, by accessing `cls.__doc__`
+* `html`: A boolean indicating if HTML output is required. `True` when used in the browsable API, and `False` when used in generating `OPTIONS` responses.
+
+Default: `'rest_framework.views.get_view_description'`
+
+---
+
## Miscellaneous settings
#### FORMAT_SUFFIX_KWARG
--
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/api-guide')
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 1bf712341508b5d9aa07fb62f55b7e495278fabf Mon Sep 17 00:00:00 2001
From: Filipe Ximenes
Date: Tue, 20 Aug 2013 16:24:13 -0300
Subject: improving documentation about object level permissions #1049
---
docs/api-guide/generic-views.md | 5 ++++-
docs/api-guide/permissions.md | 7 +++++++
2 files changed, 11 insertions(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 32a4feef..2a585f9c 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -108,7 +108,10 @@ For example:
filter = {}
for field in self.multiple_lookup_fields:
filter[field] = self.kwargs[field]
- return get_object_or_404(queryset, **filter)
+
+ obj = get_object_or_404(queryset, **filter)
+ self.check_object_permissions(self.request, obj)
+ return obj
#### `get_serializer_class(self)`
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index c6372f98..bb7343af 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -28,6 +28,13 @@ If you're writing your own views and want to enforce object level permissions,
you'll need to explicitly call the `.check_object_permissions(request, obj)` method on the view at the point at which you've retrieved the object.
This will either raise a `PermissionDenied` or `NotAuthenticated` exception, or simply return if the view has the appropriate permissions.
+For example:
+
+ def get_object(self):
+ obj = get_object_or_404(self.get_queryset())
+ self.check_object_permissions(self.request, obj)
+ return obj
+
## Setting the permission policy
The default permission policy may be set globally, using the `DEFAULT_PERMISSION_CLASSES` setting. For example.
--
cgit v1.2.3
From 5e40e50f2b187fe2ff2e8ee63b4e39ece42f1521 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Wed, 21 Aug 2013 19:46:09 +0100
Subject: Include import paths throughout docs.
Closes #1051. Thanks to @pydanny for the report.
---
docs/api-guide/authentication.md | 14 ++++++++++++++
docs/api-guide/content-negotiation.md | 6 ++++++
docs/api-guide/fields.md | 13 ++++++++-----
docs/api-guide/filtering.md | 14 ++++++++++++++
docs/api-guide/generic-views.md | 5 +++++
docs/api-guide/pagination.md | 7 ++++++-
docs/api-guide/parsers.md | 4 ++++
docs/api-guide/permissions.md | 6 ++++++
docs/api-guide/relations.md | 11 ++++++-----
docs/api-guide/renderers.md | 9 +++++++--
docs/api-guide/reverse.md | 4 ++--
docs/api-guide/routers.md | 7 +++++++
docs/api-guide/serializers.md | 7 +++++++
docs/api-guide/status-codes.md | 1 +
docs/api-guide/testing.md | 21 ++++++++++++++++++---
docs/api-guide/throttling.md | 4 ++++
docs/api-guide/viewsets.md | 9 +++++++++
17 files changed, 124 insertions(+), 18 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index b1ab4622..f30b16ed 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -46,6 +46,11 @@ The default authentication schemes may be set globally, using the `DEFAULT_AUTHE
You can also set the authentication scheme on a per-view or per-viewset basis,
using the `APIView` class based views.
+ from rest_framework.authentication import SessionAuthentication, BasicAuthentication
+ from rest_framework.permissions import IsAuthenticated
+ from rest_framework.response import Response
+ from rest_framework.views import APIView
+
class ExampleView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
@@ -157,11 +162,16 @@ The `curl` command line tool may be useful for testing token authenticated APIs.
If you want every user to have an automatically generated Token, you can simply catch the User's `post_save` signal.
+ from django.dispatch import receiver
+ from rest_framework.authtoken.models import Token
+
@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
+Note that you'll want to ensure you place this code snippet in an installed `models.py` module, or some other location that will be imported by Django on startup.
+
If you've already created some users, you can generate tokens for all existing users like this:
from django.contrib.auth.models import User
@@ -336,6 +346,10 @@ If the `.authenticate_header()` method is not overridden, the authentication sch
The following example will authenticate any incoming request as the user given by the username in a custom request header named 'X_USERNAME'.
+ from django.contrib.auth.models import User
+ from rest_framework import authentication
+ from rest_framework import exceptions
+
class ExampleAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
username = request.META.get('X_USERNAME')
diff --git a/docs/api-guide/content-negotiation.md b/docs/api-guide/content-negotiation.md
index 2a774278..94dd59ca 100644
--- a/docs/api-guide/content-negotiation.md
+++ b/docs/api-guide/content-negotiation.md
@@ -54,6 +54,8 @@ The `select_renderer()` method should return a two-tuple of (renderer instance,
The following is a custom content negotiation class which ignores the client
request when selecting the appropriate parser or renderer.
+ from rest_framework.negotiation import BaseContentNegotiation
+
class IgnoreClientContentNegotiation(BaseContentNegotiation):
def select_parser(self, request, parsers):
"""
@@ -77,6 +79,10 @@ The default content negotiation class may be set globally, using the `DEFAULT_CO
You can also set the content negotiation used for an individual view, or viewset, using the `APIView` class based views.
+ from myapp.negotiation import IgnoreClientContentNegotiation
+ from rest_framework.response import Response
+ from rest_framework.views import APIView
+
class NoNegotiationView(APIView):
"""
An example view that does not perform content negotiation.
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index d69730c9..962c49e2 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -78,6 +78,9 @@ A generic, **read-only** field. You can use this field for any attribute that d
For example, using the following model.
+ from django.db import models
+ from django.utils.timezone import now
+
class Account(models.Model):
owner = models.ForeignKey('auth.user')
name = models.CharField(max_length=100)
@@ -85,13 +88,14 @@ For example, using the following model.
payment_expiry = models.DateTimeField()
def has_expired(self):
- now = datetime.datetime.now()
- return now > self.payment_expiry
+ return now() > self.payment_expiry
A serializer definition that looked like this:
+ from rest_framework import serializers
+
class AccountSerializer(serializers.HyperlinkedModelSerializer):
- expired = Field(source='has_expired')
+ expired = serializers.Field(source='has_expired')
class Meta:
fields = ('url', 'owner', 'name', 'expired')
@@ -125,12 +129,11 @@ The `ModelField` class is generally intended for internal use, but can be used b
This is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object. The field's constructor accepts a single argument, which is the name of the method on the serializer to be called. The method should accept a single argument (in addition to `self`), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:
- from rest_framework import serializers
from django.contrib.auth.models import User
from django.utils.timezone import now
+ from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
-
days_since_joined = serializers.SerializerMethodField('get_days_since_joined')
class Meta:
diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md
index 05c997a3..649462da 100644
--- a/docs/api-guide/filtering.md
+++ b/docs/api-guide/filtering.md
@@ -20,6 +20,10 @@ You can do so by filtering based on the value of `request.user`.
For example:
+ from myapp.models import Purchase
+ from myapp.serializers import PurchaseSerializer
+ from rest_framework import generics
+
class PurchaseList(generics.ListAPIView)
serializer_class = PurchaseSerializer
@@ -90,6 +94,11 @@ The default filter backends may be set globally, using the `DEFAULT_FILTER_BACKE
You can also set the filter backends on a per-view, or per-viewset basis,
using the `GenericAPIView` class based views.
+ from django.contrib.auth.models import User
+ from myapp.serializers import UserSerializer
+ from rest_framework import filters
+ from rest_framework import generics
+
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer = UserSerializer
@@ -150,6 +159,11 @@ This will automatically create a `FilterSet` class for the given fields, and wil
For more advanced filtering requirements you can specify a `FilterSet` class that should be used by the view. For example:
+ import django_filters
+ from myapp.models import Product
+ from myapp.serializers import ProductSerializer
+ from rest_framework import generics
+
class ProductFilter(django_filters.FilterSet):
min_price = django_filters.NumberFilter(lookup_type='gte')
max_price = django_filters.NumberFilter(lookup_type='lte')
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 32a4feef..7f754df8 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -17,6 +17,11 @@ If the generic views don't suit the needs of your API, you can drop down to usin
Typically when using the generic views, you'll override the view, and set several class attributes.
+ from django.contrib.auth.models import User
+ from myapp.serializers import UserSerializer
+ from rest_framework import generics
+ from rest_framework.permissions import IsAdminUser
+
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md
index 912ce41b..ca0174b7 100644
--- a/docs/api-guide/pagination.md
+++ b/docs/api-guide/pagination.md
@@ -13,6 +13,7 @@ REST framework includes a `PaginationSerializer` class that makes it easy to ret
Let's start by taking a look at an example from the Django documentation.
from django.core.paginator import Paginator
+
objects = ['john', 'paul', 'george', 'ringo']
paginator = Paginator(objects, 2)
page = paginator.page(1)
@@ -22,6 +23,7 @@ Let's start by taking a look at an example from the Django documentation.
At this point we've got a page object. If we wanted to return this page object as a JSON response, we'd need to provide the client with context such as next and previous links, so that it would be able to page through the remaining results.
from rest_framework.pagination import PaginationSerializer
+
serializer = PaginationSerializer(instance=page)
serializer.data
# {'count': 4, 'next': '?page=2', 'previous': None, 'results': [u'john', u'paul']}
@@ -114,6 +116,9 @@ You can also override the name used for the object list field, by setting the `r
For example, to nest a pair of links labelled 'prev' and 'next', and set the name for the results field to 'objects', you might use something like this.
+ from rest_framework import pagination
+ from rest_framework import serializers
+
class LinksSerializer(serializers.Serializer):
next = pagination.NextPageField(source='*')
prev = pagination.PreviousPageField(source='*')
@@ -135,7 +140,7 @@ To have your custom pagination serializer be used by default, use the `DEFAULT_P
Alternatively, to set your custom pagination serializer on a per-view basis, use the `pagination_serializer_class` attribute on a generic class based view:
- class PaginatedListView(ListAPIView):
+ class PaginatedListView(generics.ListAPIView):
model = ExampleModel
pagination_serializer_class = CustomPaginationSerializer
paginate_by = 10
diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md
index 5bd79a31..d3c42b1c 100644
--- a/docs/api-guide/parsers.md
+++ b/docs/api-guide/parsers.md
@@ -37,6 +37,10 @@ The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSE
You can also set the renderers used for an individual view, or viewset,
using the `APIView` class based views.
+ from rest_framework.parsers import YAMLParser
+ from rest_framework.response import Response
+ from rest_framework.views import APIView
+
class ExampleView(APIView):
"""
A view that can accept POST requests with YAML content.
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index c6372f98..a3d86ed4 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -47,6 +47,10 @@ If not specified, this setting defaults to allowing unrestricted access:
You can also set the authentication policy on a per-view, or per-viewset basis,
using the `APIView` class based views.
+ from rest_framework.permissions import IsAuthenticated
+ from rest_framework.responses import Response
+ from rest_framework.views import APIView
+
class ExampleView(APIView):
permission_classes = (IsAuthenticated,)
@@ -157,6 +161,8 @@ For more details see the [2.2 release announcement][2.2-announcement].
The following is an example of a permission class that checks the incoming request's IP address against a blacklist, and denies the request if the IP has been blacklisted.
+ from rest_framework import permissions
+
class BlacklistPermission(permissions.BasePermission):
"""
Global permission check for blacklisted IPs.
diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md
index 829a3c54..aa14bc72 100644
--- a/docs/api-guide/relations.md
+++ b/docs/api-guide/relations.md
@@ -76,7 +76,7 @@ This field is read only.
For example, the following serializer:
class AlbumSerializer(serializers.ModelSerializer):
- tracks = PrimaryKeyRelatedField(many=True, read_only=True)
+ tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Album
@@ -110,8 +110,8 @@ By default this field is read-write, although you can change this behavior using
For example, the following serializer:
class AlbumSerializer(serializers.ModelSerializer):
- tracks = HyperlinkedRelatedField(many=True, read_only=True,
- view_name='track-detail')
+ tracks = serializers.HyperlinkedRelatedField(many=True, read_only=True,
+ view_name='track-detail')
class Meta:
model = Album
@@ -148,7 +148,8 @@ By default this field is read-write, although you can change this behavior using
For example, the following serializer:
class AlbumSerializer(serializers.ModelSerializer):
- tracks = SlugRelatedField(many=True, read_only=True, slug_field='title')
+ tracks = serializers.SlugRelatedField(many=True, read_only=True,
+ slug_field='title')
class Meta:
model = Album
@@ -183,7 +184,7 @@ When using `SlugRelatedField` as a read-write field, you will normally want to e
This field can be applied as an identity relationship, such as the `'url'` field on a HyperlinkedModelSerializer. It can also be used for an attribute on the object. For example, the following serializer:
class AlbumSerializer(serializers.HyperlinkedModelSerializer):
- track_listing = HyperlinkedIdentityField(view_name='track-list')
+ track_listing = serializers.HyperlinkedIdentityField(view_name='track-list')
class Meta:
model = Album
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index bb3d2015..7fc1fc1f 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -30,11 +30,16 @@ The default set of renderers may be set globally, using the `DEFAULT_RENDERER_CL
You can also set the renderers used for an individual view, or viewset,
using the `APIView` class based views.
+ from django.contrib.auth.models import User
+ from rest_framework.renderers import JSONRenderer, YAMLRenderer
+ from rest_framework.response import Response
+ from rest_framework.views import APIView
+
class UserCountView(APIView):
"""
- A view that returns the count of active users, in JSON or JSONp.
+ A view that returns the count of active users, in JSON or YAML.
"""
- renderer_classes = (JSONRenderer, JSONPRenderer)
+ renderer_classes = (JSONRenderer, YAMLRenderer)
def get(self, request, format=None):
user_count = User.objects.filter(active=True).count()
diff --git a/docs/api-guide/reverse.md b/docs/api-guide/reverse.md
index 94262366..383eca4c 100644
--- a/docs/api-guide/reverse.md
+++ b/docs/api-guide/reverse.md
@@ -27,13 +27,13 @@ Has the same behavior as [`django.core.urlresolvers.reverse`][reverse], except t
You should **include the request as a keyword argument** to the function, for example:
- import datetime
from rest_framework.reverse import reverse
from rest_framework.views import APIView
+ from django.utils.timezone import now
class APIRootView(APIView):
def get(self, request):
- year = datetime.datetime.now().year
+ year = now().year
data = {
...
'year-summary-url': reverse('year-summary', args=[year], request=request)
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 072a2e79..fb48197e 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -14,6 +14,8 @@ 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`.
+ from rest_framework import routers
+
router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
@@ -40,6 +42,9 @@ The example above would generate the following URL patterns:
Any methods on the viewset decorated with `@link` or `@action` will also be routed.
For example, given a method like this on the `UserViewSet` class:
+ from myapp.permissions import IsAdminOrIsSelf
+ from rest_framework.decorators import action
+
@action(permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
...
@@ -120,6 +125,8 @@ The arguments to the `Route` named tuple are:
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
+
class ReadOnlyRouter(SimpleRouter):
"""
A router for read-only APIs, which doesn't use trailing slashes.
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index bbc8d019..d9fd4643 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -28,6 +28,8 @@ We'll declare a serializer that we can use to serialize and deserialize `Comment
Declaring a serializer looks very similar to declaring a form:
+ from rest_framework import serializers
+
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
@@ -59,6 +61,8 @@ We can now use `CommentSerializer` to serialize a comment, or list of comments.
At this point we've translated the model instance into Python native datatypes. To finalise the serialization process we render the data into `json`.
+ from rest_framework.renderers import JSONRenderer
+
json = JSONRenderer().render(serializer.data)
json
# '{"email": "leila@example.com", "content": "foo bar", "created": "2012-08-22T16:20:09.822"}'
@@ -67,6 +71,9 @@ At this point we've translated the model instance into Python native datatypes.
Deserialization is similar. First we parse a stream into Python native datatypes...
+ from StringIO import StringIO
+ from rest_framework.parsers import JSONParser
+
stream = StringIO(json)
data = JSONParser().parse(stream)
diff --git a/docs/api-guide/status-codes.md b/docs/api-guide/status-codes.md
index db2e059c..409f659b 100644
--- a/docs/api-guide/status-codes.md
+++ b/docs/api-guide/status-codes.md
@@ -9,6 +9,7 @@
Using bare status codes in your responses isn't recommended. REST framework includes a set of named constants that you can use to make more code more obvious and readable.
from rest_framework import status
+ from rest_framework.response import Response
def empty_view(self):
content = {'please move along': 'nothing to see here'}
diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md
index 92f8d54a..b3880f8f 100644
--- a/docs/api-guide/testing.md
+++ b/docs/api-guide/testing.md
@@ -16,6 +16,8 @@ Extends [Django's existing `RequestFactory` class][requestfactory].
The `APIRequestFactory` class supports an almost identical API to Django's standard `RequestFactory` class. This means the that standard `.get()`, `.post()`, `.put()`, `.patch()`, `.delete()`, `.head()` and `.options()` methods are all available.
+ from rest_framework.test import APIRequestFactory
+
# Using the standard RequestFactory API to create a form POST request
factory = APIRequestFactory()
request = factory.post('/notes/', {'title': 'new idea'})
@@ -49,6 +51,8 @@ For example, using `APIRequestFactory`, you can make a form PUT request like so:
Using Django's `RequestFactory`, you'd need to explicitly encode the data yourself:
+ from django.test.client import encode_multipart, RequestFactory
+
factory = RequestFactory()
data = {'title': 'remember to email dave'}
content = encode_multipart('BoUnDaRyStRiNg', data)
@@ -72,6 +76,12 @@ To forcibly authenticate a request, use the `force_authenticate()` method.
The signature for the method is `force_authenticate(request, user=None, token=None)`. When making the call, either or both of the user and token may be set.
+For example, when forcibly authenticating using a token, you might do something like the following:
+
+ user = User.objects.get(username='olivia')
+ request = factory.get('/accounts/django-superstars/')
+ force_authenticate(request, user=user, token=user.token)
+
---
**Note**: When using `APIRequestFactory`, the object that is returned is Django's standard `HttpRequest`, and not REST framework's `Request` object, which is only generated once the view is called.
@@ -105,6 +115,8 @@ Extends [Django's existing `Client` class][client].
The `APIClient` class supports the same request interface as `APIRequestFactory`. This means the that standard `.get()`, `.post()`, `.put()`, `.patch()`, `.delete()`, `.head()` and `.options()` methods are all available. For example:
+ from rest_framework.test import APIClient
+
client = APIClient()
client.post('/notes/', {'title': 'new idea'}, format='json')
@@ -131,8 +143,11 @@ The `login` method is appropriate for testing APIs that use session authenticati
The `credentials` method can be used to set headers that will then be included on all subsequent requests by the test client.
+ from rest_framework.authtoken.models import Token
+ from rest_framework.test import APIClient
+
# Include an appropriate `Authorization:` header on all requests.
- token = Token.objects.get(username='lauren')
+ token = Token.objects.get(user__username='lauren')
client = APIClient()
client.credentials(HTTP_AUTHORIZATION='Token ' + token.key)
@@ -190,10 +205,10 @@ You can use any of REST framework's test case classes as you would for the regul
Ensure we can create a new account object.
"""
url = reverse('account-list')
- data = {'name': 'DabApps'}
+ expected = {'name': 'DabApps'}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
- self.assertEqual(response.data, data)
+ self.assertEqual(response.data, expected)
---
diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md
index 56f32f58..42f9c228 100644
--- a/docs/api-guide/throttling.md
+++ b/docs/api-guide/throttling.md
@@ -43,6 +43,10 @@ The rate descriptions used in `DEFAULT_THROTTLE_RATES` may include `second`, `mi
You can also set the throttling policy on a per-view or per-viewset basis,
using the `APIView` class based views.
+ from rest_framework.response import Response
+ from rest_framework.throttling import UserRateThrottle
+ from rest_framework.views import APIView
+
class ExampleView(APIView):
throttle_classes = (UserRateThrottle,)
diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md
index 0c68afb0..61f9d2f8 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -19,6 +19,12 @@ Typically, rather than explicitly registering the views in a viewset in the urlc
Let's define a simple viewset that can be used to list or retrieve all the users in the system.
+ from django.contrib.auth.models import User
+ from django.shortcuts import get_object_or_404
+ from myapps.serializers import UserSerializer
+ from rest_framework import viewsets
+ from rest_framewor.responses import Response
+
class UserViewSet(viewsets.ViewSet):
"""
A simple ViewSet that for listing or retrieving users.
@@ -41,6 +47,9 @@ If we need to, we can bind this viewset into two separate views, like so:
Typically we wouldn't do this, but would instead register the viewset with a router, and allow the urlconf to be automatically generated.
+ from myapp.views import UserViewSet
+ from rest_framework.routers import DefaultRouter
+
router = DefaultRouter()
router.register(r'users', UserViewSet)
urlpatterns = router.urls
--
cgit v1.2.3
From cf6ae397db1353370fef05df99a8d321806a6f58 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Wed, 21 Aug 2013 19:57:30 +0100
Subject: Docs tweaking around `check_object_permissions`
---
docs/api-guide/generic-views.md | 2 ++
docs/api-guide/permissions.md | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 281a0481..931cae54 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -118,6 +118,8 @@ For example:
self.check_object_permissions(self.request, obj)
return obj
+Note that if your API doesn't include any object level permissions, you may optionally exclude the ``self.check_object_permissions, and simply return the object from the `get_object_or_404` lookup.
+
#### `get_serializer_class(self)`
Returns the class that should be used for the serializer. Defaults to returning the `serializer_class` attribute, or dynamically generating a serializer class if the `model` shortcut is being used.
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index 6b80a98c..12aa4c18 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -25,7 +25,8 @@ Object level permissions are run by REST framework's generic views when `.get_ob
As with view level permissions, an `exceptions.PermissionDenied` exception will be raised if the user is not allowed to act on the given object.
If you're writing your own views and want to enforce object level permissions,
-you'll need to explicitly call the `.check_object_permissions(request, obj)` method on the view at the point at which you've retrieved the object.
+or if you override the `get_object` method on a generic view, then you'll need to explicitly call the `.check_object_permissions(request, obj)` method on the view at the point at which you've retrieved the object.
+
This will either raise a `PermissionDenied` or `NotAuthenticated` exception, or simply return if the view has the appropriate permissions.
For example:
--
cgit v1.2.3
From ec5955101b4b15b828ac5b6fc54e8d10f2a7c64a Mon Sep 17 00:00:00 2001
From: Ramiro Morales
Date: Thu, 22 Aug 2013 12:40:12 -0300
Subject: Update parsers.md
s/renderers/parsers/---
docs/api-guide/parsers.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md
index d3c42b1c..1030fcb6 100644
--- a/docs/api-guide/parsers.md
+++ b/docs/api-guide/parsers.md
@@ -34,7 +34,7 @@ The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSE
)
}
-You can also set the renderers used for an individual view, or viewset,
+You can also set the parsers used for an individual view, or viewset,
using the `APIView` class based views.
from rest_framework.parsers import YAMLParser
--
cgit v1.2.3
From dba602781355f6ee0cbc34775209cd37a52ca4d4 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 23 Aug 2013 11:27:12 +0100
Subject: Add missing period.
---
docs/api-guide/testing.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md
index b3880f8f..35c1f766 100644
--- a/docs/api-guide/testing.md
+++ b/docs/api-guide/testing.md
@@ -2,7 +2,7 @@
# Testing
-> Code without tests is broken as designed
+> Code without tests is broken as designed.
>
> — [Jacob Kaplan-Moss][cite]
--
cgit v1.2.3
From 436e66a42db21b52fd5e1582011d2f0f7f81f9c7 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 23 Aug 2013 16:45:55 +0100
Subject: JSON responses should not include a charset
---
docs/api-guide/renderers.md | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index 7fc1fc1f..d46d0568 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -88,7 +88,7 @@ The client may additionally include an `'indent'` media type parameter, in which
**.format**: `'.json'`
-**.charset**: `utf-8`
+**.charset**: `None`
## UnicodeJSONRenderer
@@ -110,7 +110,7 @@ Both the `JSONRenderer` and `UnicodeJSONRenderer` styles conform to [RFC 4627][r
**.format**: `'.json'`
-**.charset**: `utf-8`
+**.charset**: `None`
## JSONPRenderer
@@ -295,12 +295,15 @@ By default renderer classes are assumed to be using the `UTF-8` encoding. To us
Note that if a renderer class returns a unicode string, then the response content will be coerced into a bytestring by the `Response` class, with the `charset` attribute set on the renderer used to determine the encoding.
-If the renderer returns a bytestring representing raw binary content, you should set a charset value of `None`, which will ensure the `Content-Type` header of the response will not have a `charset` value set. Doing so will also ensure that the browsable API will not attempt to display the binary content as a string.
+If the renderer returns a bytestring representing raw binary content, you should set a charset value of `None`, which will ensure the `Content-Type` header of the response will not have a `charset` value set.
+
+In some cases you may also want to set the `render_style` attribute to `'binary'`. Doing so will also ensure that the browsable API will not attempt to display the binary content as a string.
class JPEGRenderer(renderers.BaseRenderer):
media_type = 'image/jpeg'
format = 'jpg'
charset = None
+ render_style = 'binary'
def render(self, data, media_type=None, renderer_context=None):
return data
--
cgit v1.2.3
From c7847ebc45f38e4d735b77c54ad1a55c87242fac Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 23 Aug 2013 17:10:50 +0100
Subject: Docs for HTMLFormRenderer
---
docs/api-guide/renderers.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index d46d0568..c116ceda 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -212,6 +212,18 @@ You can use `TemplateHTMLRenderer` either to return regular HTML pages using RES
See also: `TemplateHTMLRenderer`
+## HTMLFormRenderer
+
+Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing `