From d8eb9e6d45c227582559ec4318b1f92562c718da Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 29 Aug 2014 10:48:16 +0100
Subject: Docs whitespace fix.
---
docs/api-guide/generic-views.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index b1c4e65a..d30b7f9b 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -19,8 +19,8 @@ Typically when using the generic views, you'll override the view, and set severa
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
- from rest_framework import generics
- from rest_framework.permissions import IsAdminUser
+ from rest_framework import generics
+ from rest_framework.permissions import IsAdminUser
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
--
cgit v1.2.3
From 0f8fdf4e72b67ff46474c13c8b532bf319a58099 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 29 Aug 2014 10:57:24 +0100
Subject: Remove `allow_empty`.
Closes #1774.
---
docs/api-guide/generic-views.md | 2 --
1 file changed, 2 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index d30b7f9b..49be0cae 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -212,8 +212,6 @@ Provides a `.list(request, *args, **kwargs)` method, that implements listing a q
If the queryset is populated, this returns a `200 OK` response, with a serialized representation of the queryset as the body of the response. The response data may optionally be paginated.
-If the queryset is empty this returns a `200 OK` response, unless the `.allow_empty` attribute on the view is set to `False`, in which case it will return a `404 Not Found`.
-
## CreateModelMixin
Provides a `.create(request, *args, **kwargs)` method, that implements creating and saving a new model instance.
--
cgit v1.2.3
From 19b8f779de82fa4737b37fb4359145af0b07a56c Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Thu, 11 Sep 2014 20:43:44 +0100
Subject: Throttles now use Retry-After header and no longer support the custom
style
---
docs/api-guide/throttling.md | 2 ++
1 file changed, 2 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md
index 832304f1..16a7457b 100644
--- a/docs/api-guide/throttling.md
+++ b/docs/api-guide/throttling.md
@@ -178,6 +178,8 @@ To create a custom throttle, override `BaseThrottle` and implement `.allow_reque
Optionally you may also override the `.wait()` method. If implemented, `.wait()` should return a recommended number of seconds to wait before attempting the next request, or `None`. The `.wait()` method will only be called if `.allow_request()` has previously returned `False`.
+If the `.wait()` method is implemented and the request is throttled, then a `Retry-After` header will be included in the response.
+
## Example
The following is an example of a rate throttle, that will randomly throttle 1 in every 10 requests.
--
cgit v1.2.3
From f95e7fae38968f58e742b93842bda9110a61b9f7 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 12 Sep 2014 12:40:53 +0100
Subject: Updating docs
---
docs/api-guide/renderers.md | 29 +++++----------------------
docs/api-guide/settings.md | 48 ++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 50 insertions(+), 27 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index 7a3429bf..b1adf31f 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -74,37 +74,18 @@ If your API includes views that can serve both regular webpages and API response
Renders the request data into `JSON`, using utf-8 encoding.
-Note that non-ascii characters will be rendered using JSON's `\uXXXX` character escape. For example:
+Note that the default style is to include unicode characters, and render the response using a compact style with no uneccessary whitespace:
- {"unicode black star": "\u2605"}
+ {"unicode black star":"★","value":999}
The client may additionally include an `'indent'` media type parameter, in which case the returned `JSON` will be indented. For example `Accept: application/json; indent=4`.
{
- "unicode black star": "\u2605"
+ "unicode black star": "★",
+ "value": 999
}
-**.media_type**: `application/json`
-
-**.format**: `'.json'`
-
-**.charset**: `None`
-
-## UnicodeJSONRenderer
-
-Renders the request data into `JSON`, using utf-8 encoding.
-
-Note that non-ascii characters will not be character escaped. For example:
-
- {"unicode black star": "★"}
-
-The client may additionally include an `'indent'` media type parameter, in which case the returned `JSON` will be indented. For example `Accept: application/json; indent=4`.
-
- {
- "unicode black star": "★"
- }
-
-Both the `JSONRenderer` and `UnicodeJSONRenderer` styles conform to [RFC 4627][rfc4627], and are syntactically valid JSON.
+The default JSON encoding style can be altered using the `UNICODE_JSON` and `COMPACT_JSON` settings keys.
**.media_type**: `application/json`
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 27a09163..6a855c92 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -265,7 +265,7 @@ A format string that should be used by default for rendering the output of `Date
May be any of `None`, `'iso-8601'` or a Python [strftime format][strftime] string.
-Default: `None`
+Default: `'iso-8601'`
#### DATETIME_INPUT_FORMATS
@@ -281,7 +281,7 @@ A format string that should be used by default for rendering the output of `Date
May be any of `None`, `'iso-8601'` or a Python [strftime format][strftime] string.
-Default: `None`
+Default: `'iso-8601'`
#### DATE_INPUT_FORMATS
@@ -297,7 +297,7 @@ A format string that should be used by default for rendering the output of `Time
May be any of `None`, `'iso-8601'` or a Python [strftime format][strftime] string.
-Default: `None`
+Default: `'iso-8601'`
#### TIME_INPUT_FORMATS
@@ -309,6 +309,46 @@ Default: `['iso-8601']`
---
+## Encodings
+
+#### UNICODE_JSON
+
+When set to `True`, JSON responses will allow unicode characters in responses. For example:
+
+ {"unicode black star":"★"}
+
+When set to `False`, JSON responses will escape non-ascii characters, like so:
+
+ {"unicode black star":"\u2605"}
+
+Both styles conform to [RFC 4627][rfc4627], and are syntactically valid JSON. The unicode style is prefered as being more user-friendly when inspecting API responses.
+
+Default: `True`
+
+#### COMPACT_JSON
+
+When set to `True`, JSON responses will return compact representations, with no spacing after `':'` and `','` characters. For example:
+
+ {"is_admin":false,"email":"jane@example"}
+
+When set to `False`, JSON responses will return slightly more verbose representations, like so:
+
+ {"is_admin": false, "email": "jane@example"}
+
+The default style is to return minified responses, in line with [Heroku's API design guidelines][heroku-minified-json].
+
+Default: `True`
+
+#### COERCE_DECIMAL_TO_STRING
+
+When returning decimal objects in API representations that do not support a native decimal type, it is normally best to return the value as a string. This avoids the loss of precision that occurs with binary floating point implementations.
+
+When set to `True`, the serializer `DecimalField` class will return strings instead of `Decimal` objects. When set to `False`, serializers will return `Decimal` objects, which the default JSON encoder will return as floats.
+
+Default: `True`
+
+---
+
## 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.**
@@ -378,4 +418,6 @@ An integer of 0 or more, that may be used to specify the number of application p
Default: `None`
[cite]: http://www.python.org/dev/peps/pep-0020/
+[rfc4627]: http://www.ietf.org/rfc/rfc4627.txt
+[heroku-minified-json]: https://github.com/interagent/http-api-design#keep-json-minified-in-all-responses
[strftime]: http://docs.python.org/2/library/time.html#time.strftime
--
cgit v1.2.3
From 4fceceae7d1abf4d841677daee2636273ff09de8 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 12 Sep 2014 20:09:08 +0100
Subject: DecimalField documentation
---
docs/api-guide/fields.md | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index bfbff2ad..f0778318 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -274,7 +274,27 @@ Corresponds to `django.db.models.fields.FloatField`.
## DecimalField
-A decimal representation.
+A decimal representation, represented in Python by a Decimal instance.
+
+Has two required arguments:
+
+- `max_digits` The maximum number of digits allowed in the number. Note that this number must be greater than or equal to decimal_places.
+
+- `decimal_places` The number of decimal places to store with the number.
+
+For example, to validate numbers up to 999 with a resolution of 2 decimal places, you would use:
+
+ serializers.DecimalField(max_digits=5, decimal_places=2)
+
+And to validate numbers up to anything lesss than one billion with a resolution of 10 decimal places:
+
+ serializers.DecimalField(max_digits=19, decimal_places=10)
+
+This field also takes an optional argument, `coerce_to_string`. If set to `True` the representation will be output as a string. If set to `False` the representation will be left as a `Decimal` instance and the final representation will be determined by the renderer.
+
+If unset, this will default to the same value as the `COERCE_DECIMAL_TO_STRING` setting, which is `True` unless set otherwise.
+
+**Signature:** `DecimalField(max_digits, decimal_places, coerce_to_string=None)`
Corresponds to `django.db.models.fields.DecimalField`.
--
cgit v1.2.3
From dfab9af294972720f59890967cd9ae1a6c0796b6 Mon Sep 17 00:00:00 2001
From: Craig de Stigter
Date: Fri, 3 Oct 2014 08:41:18 +1300
Subject: Minor: fix spelling and grammar, mostly in 3.0 announcement
---
docs/api-guide/fields.md | 2 +-
docs/api-guide/renderers.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index f0778318..292a51d8 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -286,7 +286,7 @@ For example, to validate numbers up to 999 with a resolution of 2 decimal places
serializers.DecimalField(max_digits=5, decimal_places=2)
-And to validate numbers up to anything lesss than one billion with a resolution of 10 decimal places:
+And to validate numbers up to anything less than one billion with a resolution of 10 decimal places:
serializers.DecimalField(max_digits=19, decimal_places=10)
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index 2e1c892f..db7436c2 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -74,7 +74,7 @@ If your API includes views that can serve both regular webpages and API response
Renders the request data into `JSON`, using utf-8 encoding.
-Note that the default style is to include unicode characters, and render the response using a compact style with no uneccessary whitespace:
+Note that the default style is to include unicode characters, and render the response using a compact style with no unnecessary whitespace:
{"unicode black star":"★","value":999}
--
cgit v1.2.3
From 6637b2fae0dab65447ff0bfd5ac0ba68644446eb Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Thu, 9 Oct 2014 11:08:26 +0100
Subject: Document the Metadata API
---
docs/api-guide/metadata.md | 103 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 docs/api-guide/metadata.md
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/metadata.md b/docs/api-guide/metadata.md
new file mode 100644
index 00000000..c3f036b7
--- /dev/null
+++ b/docs/api-guide/metadata.md
@@ -0,0 +1,103 @@
+
+
+# Metadata
+
+> [The `OPTIONS`] method allows a client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.
+>
+> — [RFC7231, Section 4.3.7.][cite]
+
+REST framework includes a configurable mechanism for determining how your API should respond to `OPTIONS` requests. This allows you to return API schema or other resource information.
+
+There are not currently any widely adopted conventions for exactly what style of response should be returned for HTTP `OPTIONS` requests, so we provide an ad-hoc style that returns some useful information.
+
+Here's an example response that demonstrates the information that is returned by default.
+
+ HTTP 200 OK
+ Allow: GET, POST, HEAD, OPTIONS
+ Content-Type: application/json
+
+ {
+ "name": "To Do List",
+ "description": "List existing 'To Do' items, or create a new item.",
+ "renders": [
+ "application/json",
+ "text/html"
+ ],
+ "parses": [
+ "application/json",
+ "application/x-www-form-urlencoded",
+ "multipart/form-data"
+ ],
+ "actions": {
+ "POST": {
+ "note": {
+ "type": "string",
+ "required": false,
+ "read_only": false,
+ "label": "title",
+ "max_length": 100
+ }
+ }
+ }
+ }
+
+## Setting the metadata scheme
+
+You can set the metadata class globally using the `'DEFAULT_METADATA_CLASS'` settings key:
+
+ REST_FRAMEWORK = {
+ 'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata'
+ }
+
+Or you can set the metadata class individually for a view:
+
+ class APIRoot(APIView):
+ metadata_class = APIRootMetadata
+
+ def get(self, request, format=None):
+ return Response({
+ ...
+ })
+
+The REST framework package only includes a single metadata class implementation, named `SimpleMetadata`. If you want to use an alternative style you'll need to implement a custom metadata class.
+
+## Creating schema endpoints
+
+If you have specific requirements for creating schema endpoints that are accessed with regular `GET` requests, you might consider re-using the metadata API for doing so.
+
+For example, the following additional route could be used on a viewset to provide a linkable schema endpoint.
+
+ @list_route(methods=['GET'])
+ def schema(self, request):
+ meta = self.metadata_class()
+ data = meta.determine_metadata(request, self)
+ return Response(data)
+
+There are a couple of reasons that you might choose to take this approach, including that `OPTIONS` responses [are not cacheable][no-options].
+
+---
+
+# Custom metadata classes
+
+If you want to provide a custom metadata class you should override `BaseMetadata` and implement the `determine_metadata(self, request, view)` method.
+
+Useful things that you might want to do could include returning schema information, using a format such as [JSON schema][json-schema], or returning debug information to admin users.
+
+## Example
+
+The following class could be used to limit the information that is returned to `OPTIONS` requests.
+
+ class MinimalMetadata(BaseMetadata):
+ """
+ Don't include field and other information for `OPTIONS` requests.
+ Just return the name and description.
+ """
+ def determine_metadata(self, request, view):
+ return {
+ 'name': view.get_view_name(),
+ 'description': view.get_view_description()
+ }
+
+[cite]: http://tools.ietf.org/html/rfc7231#section-4.3.7
+[no-options]: https://www.mnot.net/blog/2012/10/29/NO_OPTIONS
+[json-schema]: http://json-schema.org/
--
cgit v1.2.3
From babdc78e61ac915fa4a01bdfb04e11a32dbf5d79 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Thu, 9 Oct 2014 11:39:01 +0100
Subject: Typo
---
docs/api-guide/validators.md | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 docs/api-guide/validators.md
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/validators.md b/docs/api-guide/validators.md
new file mode 100644
index 00000000..e69de29b
--
cgit v1.2.3
From 113a28ed8ad65d912180e8be7a92b679251b0249 Mon Sep 17 00:00:00 2001
From: konradhalas
Date: Thu, 16 Oct 2014 13:48:18 +0200
Subject: Add djoser to authentication docs.
---
docs/api-guide/authentication.md | 5 +++++
1 file changed, 5 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index 0ec5bad1..b355012e 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -415,6 +415,10 @@ The [HawkREST][hawkrest] library builds on the [Mohawk][mohawk] library to let y
HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a way to achieve origin authentication and message integrity for HTTP messages. Similar to [Amazon's HTTP Signature scheme][amazon-http-signature], used by many of its services, it permits stateless, per-request authentication. [Elvio Toccalino][etoccalino] maintains the [djangorestframework-httpsignature][djangorestframework-httpsignature] package which provides an easy to use HTTP Signature Authentication mechanism.
+## Djoser
+
+[Djoser][djoser] library provides a set of views to handle basic actions such as registration, login, logout, password reset and account activation. The package works with a custom user model and it uses token based authentication. This is a ready to use REST implementation of Django authentication system.
+
[cite]: http://jacobian.org/writing/rest-worst-practices/
[http401]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2
[http403]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4
@@ -449,3 +453,4 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a
[hawk]: https://github.com/hueniverse/hawk
[mohawk]: http://mohawk.readthedocs.org/en/latest/
[mac]: http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05
+[djoser]: https://github.com/sunscrapers/djoser
--
cgit v1.2.3
From f25f05dde58908ca6885c88499e4d5984f0f3502 Mon Sep 17 00:00:00 2001
From: Andrew Conti
Date: Wed, 29 Oct 2014 16:31:36 -0400
Subject: Update authentication.md
Based on the [new documentation](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.get_user_model) for Django 1.7 we should now use:
```python
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
```
instead of:
```python
@receiver(post_save, sender=get_user_model())
```
because `get_user_model()` only works once Django has imported all models. Otherwise you'll get:
```python
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
```
When trying to start your sever after adding token authentication.
From the Docs, ( linked above as well ) :
>New in Django 1.7:
>When connecting to signals sent by the User model, you should specify the custom model using the AUTH_USER_MODEL setting.---
docs/api-guide/authentication.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index b355012e..3a5156fd 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -168,12 +168,13 @@ 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.conf import settings
from django.contrib.auth import get_user_model
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
- @receiver(post_save, sender=get_user_model())
+ @receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
--
cgit v1.2.3
From 27622058872c00e357deb7d7e86619a793ef4b41 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 31 Oct 2014 13:47:36 +0000
Subject: Validator documentation and tweaks
---
docs/api-guide/validators.md | 183 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 183 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/validators.md b/docs/api-guide/validators.md
index e69de29b..52c9e082 100644
--- a/docs/api-guide/validators.md
+++ b/docs/api-guide/validators.md
@@ -0,0 +1,183 @@
+
+
+# Validators
+
+> Validators can be useful for re-using validation logic between different types of fields.
+>
+> — [Django documentation][cite]
+
+Most of the time you're dealing with validation in REST framework you'll simply be relying on the default field validation, or writing explicit validation methods on serializer or field classes.
+
+Sometimes you'll want to place your validation logic into reusable components, so that it can easily be reused throughout your codebase. This can be achieved by using validator functions and validator classes.
+
+## Validation in REST framework
+
+Validation in Django REST framework serializers is handled a little differently to how validation works in Django's `ModelForm` class.
+
+With `ModelForm` the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class. This is advantageous for the following reasons:
+
+* It introduces a proper separation of concerns, making your code behaviour more obvious.
+* It is easy to switch between using shortcut `ModelSerializer` classes and using explicit `Serializer` classes. Any validation behaviour being used for `ModelSerializer` is simple to replicate.
+* Printing the `repr` of a serializer instance will show you exactly what validation rules it applies. There's no extra hidden validation behaviour being called on the model instance.
+
+When you're using `ModelSerializer` all of this is handled automatically for you. If you want to drop down to using a `Serializer` classes instead, then you need to define the validation rules explicitly.
+
+#### Example
+
+As an example of how REST framework uses explicit validation, we'll take a simple model class that has a field with a uniqueness constraint.
+
+ class CustomerReportRecord(models.Model):
+ time_raised = models.DateTimeField(default=timezone.now, editable=False)
+ reference = models.CharField(unique=True, max_length=20)
+ description = models.TextField()
+
+Here's a basic `ModelSerializer` that we can use for creating or updating instances of `CustomerReportRecord`:
+
+ class CustomerReportSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = CustomerReportRecord
+
+If we open up the Django shell using `manage.py shell` we can now
+
+ >>> from project.example.serializers import CustomerReportSerializer
+ >>> serializer = CustomerReportSerializer()
+ >>> print(repr(serializer))
+ CustomerReportSerializer():
+ id = IntegerField(label='ID', read_only=True)
+ time_raised = DateTimeField(read_only=True)
+ reference = CharField(max_length=20, validators=[])
+ description = CharField(style={'type': 'textarea'})
+
+The interesting bit here is the `reference` field. We can see that the uniqueness constraint is being explicitly enforced by a validator on the serializer field.
+
+Because of this more explicit style REST framework includes a few validator classes that are not available in core Django. These classes are detailed below.
+
+---
+
+## UniqueValidator
+
+This validator can be used to enforce the `unique=True` constraint on model fields.
+It takes a single required argument, and an optional `messages` argument:
+
+* `queryset` *required* - This is the queryset against which uniqueness should be enforced.
+* `message` - The error message that should be used when validation fails.
+
+This validator should be applied to *serializer fields*, like so:
+
+ slug = SlugField(
+ max_length=100,
+ validators=[UniqueValidator(queryset=BlogPost.objects.all())]
+ )
+
+## UniqueTogetherValidator
+
+This validator can be used to enforce `unique_together` constraints on model instances.
+It has two required arguments, and a single optional `messages` argument:
+
+* `queryset` *required* - This is the queryset against which uniqueness should be enforced.
+* `fields` *required* - A list or tuple of field names which should make a unique set. These must exist as fields on the serializer class.
+* `message` - The error message that should be used when validation fails.
+
+The validator should be applied to *serializer classes*, like so:
+
+ class ExampleSerializer(serializers.Serializer):
+ # ...
+ class Meta:
+ # ToDo items belong to a parent list, and have an ordering defined
+ # by the 'position' field. No two items in a given list may share
+ # the same position.
+ validators = [
+ UniqueTogetherValidator(
+ queryset=ToDoItem.objects.all(),
+ fields=('list', 'position')
+ )
+ ]
+
+## UniqueForDateValidator
+
+## UniqueForMonthValidator
+
+## UniqueForYearValidator
+
+These validators can be used to enforce the `unique_for_date`, `unique_for_month` and `unique_for_year` constraints on model instances. They take the following arguments:
+
+* `queryset` *required* - This is the queryset against which uniqueness should be enforced.
+* `field` *required* - A field name against which uniqueness in the given date range will be validated. This must exist as a field on the serializer class.
+* `date_field` *required* - A field name which will be used to determine date range for the uniqueness constrain. This must exist as a field on the serializer class.
+* `message` - The error message that should be used when validation fails.
+
+The validator should be applied to *serializer classes*, like so:
+
+ class ExampleSerializer(serializers.Serializer):
+ # ...
+ class Meta:
+ # Blog posts should have a slug that is unique for the current year.
+ validators = [
+ UniqueForYearValidator(
+ queryset=BlogPostItem.objects.all(),
+ field='slug',
+ date_field='published'
+ )
+ ]
+
+The date field that is used for the validation is always required to be present on the serializer class. You can't simply rely on a model class `default=...`, because the value being used for the default wouldn't be generated until after the validation has run.
+
+There are a couple of styles you may want to use for this depending on how you want your API to behave. If you're using `ModelSerializer` you'll probably simply rely on the defaults that REST framework generates for you, but if you are using `Serializer` or simply want more explicit control, use on of the styles demonstrated below.
+
+#### Using with a writable date field.
+
+If you want the date field to be writable the only thing worth noting is that you should ensure that it is always available in the input data, either by setting a `default` argument, or by setting `required=True`.
+
+ published = serializers.DateTimeField(required=True)
+
+#### Using with a read-only date field.
+
+If you want the date field to be visible, but not editable by the user, then set `read_only=True` and additionally set a `default=...` argument.
+
+ published = serializers.DateTimeField(read_only=True, default=timezone.now)
+
+The field will not be writable to the user, but the default value will still be passed through to the `validated_data`.
+
+#### Using with a hidden date field.
+
+If you want the date field to be entirely hidden from the user, then use `HiddenField`. This field type does not accept user input, but instead always returns it's default value to the `validated_data` in the serializer.
+
+ published = serializers.HiddenField(default=timezone.now)
+
+---
+
+# Writing custom validators
+
+You can use any of Django's existing validators, or write your own custom validators.
+
+## Function based
+
+A validator may be any callable that raises a `serializers.ValidationError` on failure.
+
+ def even_number(value):
+ if value % 2 != 0:
+ raise serializers.ValidationError('This field must be an even number.')
+
+## Class based
+
+To write a class based validator, use the `__call__` method. Class based validators are useful as they allow you to parameterize and reuse behavior.
+
+ class MultipleOf:
+ def __init__(self, base):
+ self.base = base
+
+ def __call__(self, value):
+ if value % self.base != 0
+ message = 'This field must be a multiple of %d.' % self.base
+ raise serializers.ValidationError(message)
+
+#### Using `set_context()`
+
+In some advanced cases you might want a validator to be passed the serializer field it is being used with as additional context. You can do so by declaring a `set_context` method on a class based validator.
+
+ def set_context(self, serializer_field):
+ # Determine if this is an update or a create operation.
+ # In `__call__` we can then use that information to modify the validation behavior.
+ self.is_update = serializer_field.parent.instance is not None
+
+[cite]: https://docs.djangoproject.com/en/dev/ref/validators/
--
cgit v1.2.3
From 254701230d85612cf0210d4549c2d74f410a181d Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 31 Oct 2014 13:58:40 +0000
Subject: Fix up validators docs
---
docs/api-guide/validators.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/validators.md b/docs/api-guide/validators.md
index 52c9e082..6a0ef4ff 100644
--- a/docs/api-guide/validators.md
+++ b/docs/api-guide/validators.md
@@ -8,7 +8,7 @@
Most of the time you're dealing with validation in REST framework you'll simply be relying on the default field validation, or writing explicit validation methods on serializer or field classes.
-Sometimes you'll want to place your validation logic into reusable components, so that it can easily be reused throughout your codebase. This can be achieved by using validator functions and validator classes.
+However, sometimes you'll want to place your validation logic into reusable components, so that it can easily be reused throughout your codebase. This can be achieved by using validator functions and validator classes.
## Validation in REST framework
--
cgit v1.2.3
From d27b8cc09b83bac10346effa1021493d2835b794 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 3 Nov 2014 12:00:19 +0000
Subject: PUT as create docs, and move mixin out to external gist
---
docs/api-guide/generic-views.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 49be0cae..d2836fa6 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -368,6 +368,20 @@ If you are using a mixin across multiple views, you can take this a step further
Using custom base classes is a good option if you have custom behavior that consistently needs to be repeated across a large number of views throughout your project.
+---
+
+# PUT as create
+
+Prior to version 3.0 the REST framework mixins treated `PUT` as either an update or a create operation, depending on if the object already existed or not.
+
+Allowing `PUT` as create operations is problematic, as it necessarily exposes information about the existence or non-existance of objects. It's also not obvious that transparently allowing re-creating of previously deleted instances is necessarily a better default behavior than simply returning `404` responses.
+
+Both styles "`PUT` as 404" and "`PUT` as create" can be valid in different circumstances, but from version 3.0 onwards we now use 404 behavior as the default, due to it being simpler and more obvious.
+
+If you need to generic PUT-as-create behavior you may want to include something like [this `AllowPUTAsCreateMixin` class](https://gist.github.com/tomchristie/a2ace4577eff2c603b1b) as a mixin to your views.
+
+---
+
# Third party packages
The following third party packages provide additional generic view implementations.
--
cgit v1.2.3
From 21d06a4103d1966cd6e19f7cc6f3c6e450cc1680 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 3 Nov 2014 15:03:10 +0000
Subject: Added NON_FIELD_ERRORS_KEY to serializer docs. Closes #1971.
---
docs/api-guide/settings.md | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 6a855c92..2144a2ed 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -399,6 +399,12 @@ This should be a function with the following signature:
Default: `'rest_framework.views.exception_handler'`
+#### NON_FIELD_ERRORS_KEY
+
+A string representing the key that should be used for serializer errors that do not refer to a specific field, but are instead general errors.
+
+Default: `'non_field_errors'`
+
#### URL_FIELD_NAME
A string representing the key that should be used for the URL fields generated by `HyperlinkedModelSerializer`.
--
cgit v1.2.3
From 78ac332f18c51bb151ae32f1f3d207595b0b3ca2 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 3 Nov 2014 15:08:19 +0000
Subject: Add docs on Meta inheritance. Closes #1926.
---
docs/api-guide/serializers.md | 10 ++++++++++
1 file changed, 10 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index a3694510..eeeffa13 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -413,6 +413,16 @@ Alternative representations include serializing using hyperlinks, serializing co
For full details see the [serializer relations][relations] documentation.
+## Inheritance of the 'Meta' class
+
+The inner `Meta` class on serializers is not inherited from parent classes by default. This is the same behaviour as with Django's `Model` and `ModelForm` classes. If you want the `Meta` class to inherit from a parent class you must do so explicitly. For example:
+
+ class AccountSerializer(MyBaseSerializer):
+ class Meta(MyBaseSerializer.Meta):
+ model = Account
+
+Typically we would recommend *not* using inheritance on inner Meta classes, but instead declaring all options explicitly.
+
---
# HyperlinkedModelSerializer
--
cgit v1.2.3
From 09f3eedb235b476202cbd4e5a94b883898f3f661 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 3 Nov 2014 15:23:16 +0000
Subject: Add notes re view-level and instance-level permissions checks. Closes
#1819.
---
docs/api-guide/permissions.md | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index e867a456..f3ae8171 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -183,11 +183,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 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].
+**Note**: The instance-level `has_object_permission` method will only be called if the view-level `has_permission` checks have already passed. Also note that in order for the instance-level checks to run, the view code should explicitly call `.check_object_permissions(request, obj)`. If you are using the generic views then this will be handled for you by default.
---
--
cgit v1.2.3
From 571440e143870cf38230eea7c3a49df23d1eaa7c Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Wed, 5 Nov 2014 10:53:46 +0000
Subject: Stronger calling out of 'DjangoObjectPermissionsFilter'. Closes
#1934.
---
docs/api-guide/permissions.md | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index f3ae8171..446e362e 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -146,7 +146,13 @@ As with `DjangoModelPermissions`, this permission must only be applied to views
Note that `DjangoObjectPermissions` **does not** require the `django-guardian` package, and should support other object-level backends equally well.
-As with `DjangoModelPermissions` you can use custom model permissions by overriding `DjangoModelPermissions` and setting the `.perms_map` property. Refer to the source code for details. Note that if you add a custom `view` permission for `GET`, `HEAD` and `OPTIONS` requests, you'll probably also want to consider adding the `DjangoObjectPermissionsFilter` class to ensure that list endpoints only return results including objects for which the user has appropriate view permissions.
+As with `DjangoModelPermissions` you can use custom model permissions by overriding `DjangoModelPermissions` and setting the `.perms_map` property. Refer to the source code for details.
+
+---
+
+**Note**: If you need object level `view` permissions for `GET`, `HEAD` and `OPTIONS` requests, you'll want to consider also adding the `DjangoObjectPermissionsFilter` class to ensure that list endpoints only return results including objects for which the user has appropriate view permissions.
+
+---
## TokenHasReadWriteScope
--
cgit v1.2.3
From 52507006595af4f9da34491e4211bf7ae447a457 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Wed, 5 Nov 2014 11:14:41 +0000
Subject: Add docs on request.accepted_renderer and .accepted_media_type
---
docs/api-guide/requests.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/requests.md b/docs/api-guide/requests.md
index 0696fedf..87425ed1 100644
--- a/docs/api-guide/requests.md
+++ b/docs/api-guide/requests.md
@@ -49,6 +49,20 @@ If a client sends a request with a content-type that cannot be parsed then a `Un
---
+# Content negotiation
+
+The request exposes some properties that allow you to determine the result of the content negotiation stage. This allows you to implement behaviour such as selecting a different serialisation schemes for different media types.
+
+## .accepted_renderer
+
+The renderer instance what was selected by the content negotiation stage.
+
+## .accepted_media_type
+
+A string representing the media type that was accepted by the content negotiation stage.
+
+---
+
# Authentication
REST framework provides flexible, per-request authentication, that gives you the ability to:
--
cgit v1.2.3
From b44def465054345b6099aae7bdd34b623fdc124c Mon Sep 17 00:00:00 2001
From: Brett Koonce
Date: Thu, 6 Nov 2014 23:19:26 -0800
Subject: minor spelling tweaks
---
docs/api-guide/authentication.md | 2 +-
docs/api-guide/generic-views.md | 2 +-
docs/api-guide/relations.md | 2 +-
docs/api-guide/settings.md | 6 +++---
docs/api-guide/throttling.md | 4 ++--
5 files changed, 8 insertions(+), 8 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index 3a5156fd..01774c10 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -398,7 +398,7 @@ HTTP digest authentication is a widely implemented scheme that was intended to r
## Django OAuth Toolkit
-The [Django OAuth Toolkit][django-oauth-toolkit] package provides OAuth 2.0 support, and works with Python 2.7 and Python 3.3+. The package is maintained by [Evonove][evonove] and uses the excelllent [OAuthLib][oauthlib]. The package is well documented, and comes as a recommended alternative for OAuth 2.0 support.
+The [Django OAuth Toolkit][django-oauth-toolkit] package provides OAuth 2.0 support, and works with Python 2.7 and Python 3.3+. The package is maintained by [Evonove][evonove] and uses the excellent [OAuthLib][oauthlib]. The package is well documented, and comes as a recommended alternative for OAuth 2.0 support.
## Django OAuth2 Consumer
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index d2836fa6..49a5e58f 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -374,7 +374,7 @@ Using custom base classes is a good option if you have custom behavior that cons
Prior to version 3.0 the REST framework mixins treated `PUT` as either an update or a create operation, depending on if the object already existed or not.
-Allowing `PUT` as create operations is problematic, as it necessarily exposes information about the existence or non-existance of objects. It's also not obvious that transparently allowing re-creating of previously deleted instances is necessarily a better default behavior than simply returning `404` responses.
+Allowing `PUT` as create operations is problematic, as it necessarily exposes information about the existence or non-existence of objects. It's also not obvious that transparently allowing re-creating of previously deleted instances is necessarily a better default behavior than simply returning `404` responses.
Both styles "`PUT` as 404" and "`PUT` as create" can be valid in different circumstances, but from version 3.0 onwards we now use 404 behavior as the default, due to it being simpler and more obvious.
diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md
index cc4f5585..d03a75ae 100644
--- a/docs/api-guide/relations.md
+++ b/docs/api-guide/relations.md
@@ -202,7 +202,7 @@ This field is always read-only.
**Arguments**:
-* `view_name` - The view name that should be used as the target of the relationship. If you're using [the standard router classes][routers] this wil be a string with the format `-detail`. **required**.
+* `view_name` - The view name that should be used as the target of the relationship. If you're using [the standard router classes][routers] this will be a string with the format `-detail`. **required**.
* `lookup_field` - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is `'pk'`.
* `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument.
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 2144a2ed..48af30a5 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -154,13 +154,13 @@ Default: `None`
### SEARCH_PARAM
-The name of a query paramater, which can be used to specify the search term used by `SearchFilter`.
+The name of a query parameter, which can be used to specify the search term used by `SearchFilter`.
Default: `search`
#### ORDERING_PARAM
-The name of a query paramater, which can be used to specify the ordering of results returned by `OrderingFilter`.
+The name of a query parameter, which can be used to specify the ordering of results returned by `OrderingFilter`.
Default: `ordering`
@@ -321,7 +321,7 @@ When set to `False`, JSON responses will escape non-ascii characters, like so:
{"unicode black star":"\u2605"}
-Both styles conform to [RFC 4627][rfc4627], and are syntactically valid JSON. The unicode style is prefered as being more user-friendly when inspecting API responses.
+Both styles conform to [RFC 4627][rfc4627], and are syntactically valid JSON. The unicode style is preferred as being more user-friendly when inspecting API responses.
Default: `True`
diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md
index 16a7457b..147c16ff 100644
--- a/docs/api-guide/throttling.md
+++ b/docs/api-guide/throttling.md
@@ -74,7 +74,7 @@ If you need to strictly identify unique client IP addresses, you'll need to firs
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 identifing a remote client IP can be [found here][identifing-clients].
+Further context on how the `X-Forwarded-For` header works, and identifying a remote client IP can be [found here][identifing-clients].
## Setting up the cache
@@ -85,7 +85,7 @@ If you need to use a cache other than `'default'`, you can do so by creating a c
class CustomAnonRateThrottle(AnonRateThrottle):
cache = get_cache('alternate')
-You'll need to rememeber to also set your custom throttle class in the `'DEFAULT_THROTTLE_CLASSES'` settings key, or using the `throttle_classes` view attribute.
+You'll need to remember to also set your custom throttle class in the `'DEFAULT_THROTTLE_CLASSES'` settings key, or using the `throttle_classes` view attribute.
---
--
cgit v1.2.3
From f387cd89da55ef88fcac504f5795ea9b591f3fba Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 10 Nov 2014 12:21:27 +0000
Subject: Uniqueness constraints imply a forced 'required=True'. Refs #1945
---
docs/api-guide/validators.md | 10 ++++++++++
1 file changed, 10 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/validators.md b/docs/api-guide/validators.md
index 6a0ef4ff..bb073f57 100644
--- a/docs/api-guide/validators.md
+++ b/docs/api-guide/validators.md
@@ -93,6 +93,12 @@ The validator should be applied to *serializer classes*, like so:
)
]
+---
+
+**Note**: The `UniqueTogetherValidation` class always imposes an implicit constraint that all the fields it applies to are always treated as required. Fields with `default` values are an exception to this as they always supply a value even when omitted from user input.
+
+---
+
## UniqueForDateValidator
## UniqueForMonthValidator
@@ -146,6 +152,10 @@ If you want the date field to be entirely hidden from the user, then use `Hidden
---
+**Note**: The `UniqueForValidation` classes always imposes an implicit constraint that the fields they are applied to are always treated as required. Fields with `default` values are an exception to this as they always supply a value even when omitted from user input.
+
+---
+
# Writing custom validators
You can use any of Django's existing validators, or write your own custom validators.
--
cgit v1.2.3
From fd7db776addbd5e30f132fe6846ec5c5caab5c40 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 10 Nov 2014 12:32:03 +0000
Subject: Bring UniqueValidator implementation in line with other uniquness
validators.
---
docs/api-guide/validators.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/validators.md b/docs/api-guide/validators.md
index bb073f57..a50636bc 100644
--- a/docs/api-guide/validators.md
+++ b/docs/api-guide/validators.md
@@ -16,9 +16,9 @@ Validation in Django REST framework serializers is handled a little differently
With `ModelForm` the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class. This is advantageous for the following reasons:
-* It introduces a proper separation of concerns, making your code behaviour more obvious.
-* It is easy to switch between using shortcut `ModelSerializer` classes and using explicit `Serializer` classes. Any validation behaviour being used for `ModelSerializer` is simple to replicate.
-* Printing the `repr` of a serializer instance will show you exactly what validation rules it applies. There's no extra hidden validation behaviour being called on the model instance.
+* It introduces a proper separation of concerns, making your code behavior more obvious.
+* It is easy to switch between using shortcut `ModelSerializer` classes and using explicit `Serializer` classes. Any validation behavior being used for `ModelSerializer` is simple to replicate.
+* Printing the `repr` of a serializer instance will show you exactly what validation rules it applies. There's no extra hidden validation behavior being called on the model instance.
When you're using `ModelSerializer` all of this is handled automatically for you. If you want to drop down to using a `Serializer` classes instead, then you need to define the validation rules explicitly.
--
cgit v1.2.3
From 0f508c58211051c873aae5a2d1c65a0c595e732a Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 17 Nov 2014 18:36:32 +0000
Subject: Docs for advanced default argument usage. Closes #1945
---
docs/api-guide/validators.md | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/validators.md b/docs/api-guide/validators.md
index a50636bc..ac2f3248 100644
--- a/docs/api-guide/validators.md
+++ b/docs/api-guide/validators.md
@@ -156,6 +156,38 @@ If you want the date field to be entirely hidden from the user, then use `Hidden
---
+# Advanced 'default' argument usage
+
+Validators that are applied across multiple fields in the serializer can sometimes require a field input that should not be provided by the API client, but that *is* available as input to the validator.
+
+Two patterns that you may want to use for this sort of validation include:
+
+* Using `HiddenField`. This field will be present in `validated_data` but *will not* be used in the serializer output representation.
+* Using a standard field with `read_only=True`, but that also includes a `default=…` argument. This field *will* be used in the serializer output representation, but cannot be set directly by the user.
+
+REST framework includes a couple of defaults that may be useful in this context.
+
+#### CurrentUserDefault
+
+A default class that can be used to represent the current user. In order to use this, the 'request' must have been provided as part of the context dictionary when instantiating the serializer.
+
+ owner = serializers.HiddenField(
+ default=CurrentUserDefault()
+ )
+
+#### CreateOnlyDefault
+
+A default class that can be used to *only set a default argument during create operations*. During updates the field is omitted.
+
+It takes a single argument, which is the default value or callable that should be used during create operations.
+
+ created_at = serializers.DateTimeField(
+ read_only=True,
+ default=CreateOnlyDefault(timezone.now)
+ )
+
+---
+
# Writing custom validators
You can use any of Django's existing validators, or write your own custom validators.
--
cgit v1.2.3
From 8e940a22fb292ed6b20b9e4b5da607ffca1dba2f Mon Sep 17 00:00:00 2001
From: Matthew Dapena-Tretter
Date: Fri, 21 Nov 2014 15:58:31 -0500
Subject: Clarify how permission classes are composed
all/every/AND or any/OR? all/every/AND!
---
docs/api-guide/settings.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 48af30a5..96d715ea 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -74,7 +74,7 @@ Default:
#### DEFAULT_PERMISSION_CLASSES
-A list or tuple of permission classes, that determines the default set of permissions checked at the start of a view.
+A list or tuple of permission classes, that determines the default set of permissions checked at the start of a view. Permission must be granted by every class in the list.
Default:
--
cgit v1.2.3
From 16d442dda3ee9d4ff40d067d76706959aac4c6a3 Mon Sep 17 00:00:00 2001
From: José Padilla
Date: Fri, 31 Oct 2014 09:04:39 -0400
Subject: Use MkDocs meta.source to render source code links
---
docs/api-guide/authentication.md | 2 +-
docs/api-guide/content-negotiation.md | 6 +++---
docs/api-guide/exceptions.md | 2 +-
docs/api-guide/fields.md | 4 ++--
docs/api-guide/filtering.md | 24 ++++++++++-----------
docs/api-guide/format-suffixes.md | 12 +++++------
docs/api-guide/generic-views.md | 4 ++--
docs/api-guide/pagination.md | 6 +++---
docs/api-guide/parsers.md | 6 +++---
docs/api-guide/permissions.md | 8 +++----
docs/api-guide/relations.md | 40 +++++++++++++++++------------------
docs/api-guide/renderers.md | 14 ++++++------
docs/api-guide/requests.md | 8 +++----
docs/api-guide/responses.md | 4 ++--
docs/api-guide/reverse.md | 4 ++--
docs/api-guide/routers.md | 8 +++----
docs/api-guide/serializers.md | 34 ++++++++++++++---------------
docs/api-guide/settings.md | 2 +-
docs/api-guide/status-codes.md | 6 +++---
docs/api-guide/testing.md | 6 +++---
docs/api-guide/throttling.md | 10 ++++-----
docs/api-guide/views.md | 7 +++---
docs/api-guide/viewsets.md | 2 +-
23 files changed, 110 insertions(+), 109 deletions(-)
(limited to 'docs/api-guide')
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index 01774c10..b04858e3 100755
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -1,4 +1,4 @@
-
+source: authentication.py
# Authentication
diff --git a/docs/api-guide/content-negotiation.md b/docs/api-guide/content-negotiation.md
index 94dd59ca..bc3b09fb 100644
--- a/docs/api-guide/content-negotiation.md
+++ b/docs/api-guide/content-negotiation.md
@@ -1,4 +1,4 @@
-
+source: negotiation.py
# Content negotiation
@@ -29,7 +29,7 @@ The priorities for each of the given media types would be:
If the requested view was only configured with renderers for `YAML` and `HTML`, then REST framework would select whichever renderer was listed first in the `renderer_classes` list or `DEFAULT_RENDERER_CLASSES` setting.
-For more information on the `HTTP Accept` header, see [RFC 2616][accept-header]
+For more information on the `HTTP Accept` header, see [RFC 2616][accept-header]
---
@@ -62,7 +62,7 @@ request when selecting the appropriate parser or renderer.
Select the first parser in the `.parser_classes` list.
"""
return parsers[0]
-
+
def select_renderer(self, request, renderers, format_suffix):
"""
Select the first renderer in the `.renderer_classes` list.
diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md
index e61dcfa9..8e0b1958 100644
--- a/docs/api-guide/exceptions.md
+++ b/docs/api-guide/exceptions.md
@@ -1,4 +1,4 @@
-
+source: exceptions.py
# Exceptions
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index 292a51d8..354ec966 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -1,4 +1,4 @@
-
+source: fields.py
# Serializer fields
@@ -62,7 +62,7 @@ A dictionary of error codes to error messages.
### `widget`
Used only if rendering the field to HTML.
-This argument sets the widget that should be used to render the field. For more details, and a list of available widgets, see [the Django documentation on form widgets][django-widgets].
+This argument sets the widget that should be used to render the field. For more details, and a list of available widgets, see [the Django documentation on form widgets][django-widgets].
### `label`
diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md
index cfeb4334..83977048 100644
--- a/docs/api-guide/filtering.md
+++ b/docs/api-guide/filtering.md
@@ -1,4 +1,4 @@
-
+source: filters.py
# Filtering
@@ -26,7 +26,7 @@ For example:
class PurchaseList(generics.ListAPIView):
serializer_class = PurchaseSerializer
-
+
def get_queryset(self):
"""
This view should return a list of all the purchases
@@ -38,7 +38,7 @@ For example:
## Filtering against the URL
-Another style of filtering might involve restricting the queryset based on some part of the URL.
+Another style of filtering might involve restricting the queryset based on some part of the URL.
For example if your URL config contained an entry like this:
@@ -48,7 +48,7 @@ You could then write a view that returned a purchase queryset filtered by the us
class PurchaseList(generics.ListAPIView):
serializer_class = PurchaseSerializer
-
+
def get_queryset(self):
"""
This view should return a list of all the purchases for
@@ -57,7 +57,7 @@ You could then write a view that returned a purchase queryset filtered by the us
username = self.kwargs['username']
return Purchase.objects.filter(purchaser__username=username)
-## Filtering against query parameters
+## Filtering against query parameters
A final example of filtering the initial queryset would be to determine the initial queryset based on query parameters in the url.
@@ -65,7 +65,7 @@ We can override `.get_queryset()` to deal with URLs such as `http://example.com/
class PurchaseList(generics.ListAPIView):
serializer_class = PurchaseSerializer
-
+
def get_queryset(self):
"""
Optionally restricts the returned purchases to a given user,
@@ -113,7 +113,7 @@ For instance, given the previous example, and a product with an id of `4675`, th
http://example.com/api/products/4675/?category=clothing&max_price=10.00
## Overriding the initial queryset
-
+
Note that you can use both an overridden `.get_queryset()` and generic filtering together, and everything will work as expected. For example, if `Product` had a many-to-many relationship with `User`, named `purchase`, you might want to write a view like this:
class PurchasedProductsList(generics.ListAPIView):
@@ -124,7 +124,7 @@ Note that you can use both an overridden `.get_queryset()` and generic filtering
model = Product
serializer_class = ProductSerializer
filter_class = ProductFilter
-
+
def get_queryset(self):
user = self.request.user
return user.purchase_set.all()
@@ -135,7 +135,7 @@ Note that you can use both an overridden `.get_queryset()` and generic filtering
## DjangoFilterBackend
-The `DjangoFilterBackend` class supports highly customizable field filtering, using the [django-filter package][django-filter].
+The `DjangoFilterBackend` class supports highly customizable field filtering, using the [django-filter package][django-filter].
To use REST framework's `DjangoFilterBackend`, first install `django-filter`.
@@ -216,7 +216,7 @@ This is nice, but it exposes the Django's double underscore convention as part o
And now you can execute:
http://example.com/api/products?manufacturer=foo
-
+
For more details on using filter sets see the [django-filter documentation][django-filter-docs].
---
@@ -224,7 +224,7 @@ For more details on using filter sets see the [django-filter documentation][djan
**Hints & Tips**
* By default filtering is not enabled. If you want to use `DjangoFilterBackend` remember to make sure it is installed by using the `'DEFAULT_FILTER_BACKENDS'` setting.
-* When using boolean fields, you should use the values `True` and `False` in the URL query parameters, rather than `0`, `1`, `true` or `false`. (The allowed boolean values are currently hardwired in Django's [NullBooleanSelect implementation][nullbooleanselect].)
+* When using boolean fields, you should use the values `True` and `False` in the URL query parameters, rather than `0`, `1`, `true` or `false`. (The allowed boolean values are currently hardwired in Django's [NullBooleanSelect implementation][nullbooleanselect].)
* `django-filter` supports filtering across relationships, using Django's double-underscore syntax.
* For Django 1.3 support, make sure to install `django-filter` version 0.5.4, as later versions drop support for 1.3.
@@ -316,7 +316,7 @@ Typically you'd instead control this by setting `order_by` on the initial querys
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = (filters.OrderingFilter,)
- ordering = ('username',)
+ ordering = ('username',)
The `ordering` attribute may be either a string or a list/tuple of strings.
diff --git a/docs/api-guide/format-suffixes.md b/docs/api-guide/format-suffixes.md
index 76a3367b..20c1e995 100644
--- a/docs/api-guide/format-suffixes.md
+++ b/docs/api-guide/format-suffixes.md
@@ -1,4 +1,4 @@
-
+source: urlpatterns.py
# Format suffixes
@@ -7,7 +7,7 @@ used all the time.
>
> — Roy Fielding, [REST discuss mailing list][cite]
-A common pattern for Web APIs is to use filename extensions on URLs to provide an endpoint for a given media type. For example, 'http://example.com/api/users.json' to serve a JSON representation.
+A common pattern for Web APIs is to use filename extensions on URLs to provide an endpoint for a given media type. For example, 'http://example.com/api/users.json' to serve a JSON representation.
Adding format-suffix patterns to each individual entry in the URLconf for your API is error-prone and non-DRY, so REST framework provides a shortcut to adding these patterns to your URLConf.
@@ -21,7 +21,7 @@ Arguments:
* **urlpatterns**: Required. A URL pattern list.
* **suffix_required**: Optional. A boolean indicating if suffixes in the URLs should be optional or mandatory. Defaults to `False`, meaning that suffixes are optional by default.
-* **allowed**: Optional. A list or tuple of valid format suffixes. If not provided, a wildcard format suffix pattern will be used.
+* **allowed**: Optional. A list or tuple of valid format suffixes. If not provided, a wildcard format suffix pattern will be used.
Example:
@@ -33,7 +33,7 @@ Example:
url(r'^comments/$', views.comment_list),
url(r'^comments/(?P[0-9]+)/$', views.comment_detail)
]
-
+
urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html'])
When using `format_suffix_patterns`, you must make sure to add the `'format'` keyword argument to the corresponding views. For example:
@@ -56,12 +56,12 @@ The name of the kwarg used may be modified by using the `FORMAT_SUFFIX_KWARG` se
Also note that `format_suffix_patterns` does not support descending into `include` URL patterns.
---
-
+
## Accept headers vs. format suffixes
There seems to be a view among some of the Web community that filename extensions are not a RESTful pattern, and that `HTTP Accept` headers should always be used instead.
-It is actually a misconception. For example, take the following quote from Roy Fielding discussing the relative merits of query parameter media-type indicators vs. file extension media-type indicators:
+It is actually a misconception. For example, take the following quote from Roy Fielding discussing the relative merits of query parameter media-type indicators vs. file extension media-type indicators:
“That's why I always prefer extensions. Neither choice has anything to do with REST.” — Roy Fielding, [REST discuss mailing list][cite2]
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 49a5e58f..648ece82 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -1,5 +1,5 @@
-
-
+source: mixins.py
+ generics.py
# Generic views
diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md
index e57aed1a..9b7086c5 100644
--- a/docs/api-guide/pagination.md
+++ b/docs/api-guide/pagination.md
@@ -1,4 +1,4 @@
-
+source: pagination.py
# Pagination
@@ -6,7 +6,7 @@
>
> — [Django documentation][cite]
-REST framework includes a `PaginationSerializer` class that makes it easy to return paginated data in a way that can then be rendered to arbitrary media types.
+REST framework includes a `PaginationSerializer` class that makes it easy to return paginated data in a way that can then be rendered to arbitrary media types.
## Paginating basic data
@@ -33,7 +33,7 @@ The `context` argument of the `PaginationSerializer` class may optionally includ
request = RequestFactory().get('/foobar')
serializer = PaginationSerializer(instance=page, context={'request': request})
serializer.data
- # {'count': 4, 'next': 'http://testserver/foobar?page=2', 'previous': None, 'results': [u'john', u'paul']}
+ # {'count': 4, 'next': 'http://testserver/foobar?page=2', 'previous': None, 'results': [u'john', u'paul']}
We could now return that data in a `Response` object, and it would be rendered into the correct media type.
diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md
index 72a4af64..42d77b22 100644
--- a/docs/api-guide/parsers.md
+++ b/docs/api-guide/parsers.md
@@ -1,4 +1,4 @@
-
+source: parsers.py
# Parsers
@@ -161,7 +161,7 @@ By default this will include the following keys: `view`, `request`, `args`, `kwa
## Example
-The following is an example plaintext parser that will populate the `request.DATA` property with a string representing the body of the request.
+The following is an example plaintext parser that will populate the `request.DATA` property with a string representing the body of the request.
class PlainTextParser(BaseParser):
"""
@@ -197,4 +197,4 @@ The following third party packages are also available.
[juanriaza]: https://github.com/juanriaza
[vbabiy]: https://github.com/vbabiy
[djangorestframework-msgpack]: https://github.com/juanriaza/django-rest-framework-msgpack
-[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case
\ No newline at end of file
+[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case
diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md
index 446e362e..f068f0f7 100644
--- a/docs/api-guide/permissions.md
+++ b/docs/api-guide/permissions.md
@@ -1,4 +1,4 @@
-
+source: permissions.py
# Permissions
@@ -12,7 +12,7 @@ Permission checks are always run at the very start of the view, before any other
## How permissions are determined
-Permissions in REST framework are always defined as a list of permission classes.
+Permissions in REST framework are always defined as a list of permission classes.
Before running the main body of the view each permission in the list is checked.
If any permission check fails an `exceptions.PermissionDenied` exception will be raised, and the main body of the view will not run.
@@ -220,9 +220,9 @@ As well as global permissions, that are run against all incoming requests, you c
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
- if request.method in permissions.SAFE_METHODS:
+ if request.method in permissions.SAFE_METHODS:
return True
-
+
# Instance must have an attribute named `owner`.
return obj.owner == request.user
diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md
index d03a75ae..ad981b2b 100644
--- a/docs/api-guide/relations.md
+++ b/docs/api-guide/relations.md
@@ -1,4 +1,4 @@
-
+source: relations.py
# Serializer relations
@@ -33,7 +33,7 @@ In order to explain the various types of relational fields, we'll use a couple o
class Meta:
unique_together = ('album', 'order')
order_by = 'order'
-
+
def __unicode__(self):
return '%d: %s' % (self.order, self.title)
@@ -42,10 +42,10 @@ In order to explain the various types of relational fields, we'll use a couple o
`RelatedField` may be used to represent the target of the relationship using its `__unicode__` method.
For example, the following serializer.
-
+
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.RelatedField(many=True)
-
+
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
@@ -74,10 +74,10 @@ This field is read only.
`PrimaryKeyRelatedField` may be used to represent the target of the relationship using its primary key.
For example, the following serializer:
-
+
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
-
+
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
@@ -108,11 +108,11 @@ By default this field is read-write, although you can change this behavior using
`HyperlinkedRelatedField` may be used to represent the target of the relationship using a hyperlink.
For example, the following serializer:
-
+
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.HyperlinkedRelatedField(many=True, read_only=True,
view_name='track-detail')
-
+
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
@@ -146,11 +146,11 @@ By default this field is read-write, although you can change this behavior using
`SlugRelatedField` may be used to represent the target of the relationship using a field on the target.
For example, the following serializer:
-
+
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.SlugRelatedField(many=True, read_only=True,
slug_field='title')
-
+
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
@@ -222,10 +222,10 @@ For example, the following serializer:
class Meta:
model = Track
fields = ('order', 'title')
-
+
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True)
-
+
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
@@ -262,7 +262,7 @@ For, example, we could define a relational field, to serialize a track to a cust
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackListingField(many=True)
-
+
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
@@ -302,7 +302,7 @@ If you have not set a related name for the reverse relationship, you'll need to
class AlbumSerializer(serializers.ModelSerializer):
class Meta:
- fields = ('track_set', ...)
+ fields = ('track_set', ...)
See the Django documentation on [reverse relationships][reverse-relationships] for more details.
@@ -315,14 +315,14 @@ For example, given the following model for a tag, which has a generic relationsh
class TaggedItem(models.Model):
"""
Tags arbitrary model instances using a generic relation.
-
+
See: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/
"""
tag_name = models.SlugField()
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
tagged_object = GenericForeignKey('content_type', 'object_id')
-
+
def __unicode__(self):
return self.tag
@@ -353,7 +353,7 @@ We could define a custom field that could be used to serialize tagged instances,
def to_native(self, value):
"""
Serialize tagged objects to a simple textual representation.
- """
+ """
if isinstance(value, Bookmark):
return 'Bookmark: ' + value.url
elif isinstance(value, Note):
@@ -366,7 +366,7 @@ If you need the target of the relationship to have a nested representation, you
"""
Serialize bookmark instances using a bookmark serializer,
and note instances using a note serializer.
- """
+ """
if isinstance(value, Bookmark):
serializer = BookmarkSerializer(value)
elif isinstance(value, Note):
@@ -391,7 +391,7 @@ to ``True``.
## Advanced Hyperlinked fields
-If you have very specific requirements for the style of your hyperlinked relationships you can override `HyperlinkedRelatedField`.
+If you have very specific requirements for the style of your hyperlinked relationships you can override `HyperlinkedRelatedField`.
There are two methods you'll need to override.
@@ -411,7 +411,7 @@ May raise an `ObjectDoesNotExist` exception.
### Example
-For example, if all your object URLs used both a account and a slug in the the URL to reference the object, you might create a custom field like this:
+For example, if all your object URLs used both a account and a slug in the the URL to reference the object, you might create a custom field like this:
class CustomHyperlinkedField(serializers.HyperlinkedRelatedField):
def get_url(self, obj, view_name, request, format):
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index db7436c2..035ec1d2 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -1,4 +1,4 @@
-
+source: renderers.py
# Renderers
@@ -115,7 +115,7 @@ The `jsonp` approach is essentially a browser hack, and is [only appropriate for
## YAMLRenderer
-Renders the request data into `YAML`.
+Renders the request data into `YAML`.
Requires the `pyyaml` package to be installed.
@@ -131,7 +131,7 @@ Note that non-ascii characters will be rendered using `\uXXXX` character escape.
## UnicodeYAMLRenderer
-Renders the request data into `YAML`.
+Renders the request data into `YAML`.
Requires the `pyyaml` package to be installed.
@@ -184,7 +184,7 @@ An example of a view that uses `TemplateHTMLRenderer`:
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return Response({'user': self.object}, template_name='user_detail.html')
-
+
You can use `TemplateHTMLRenderer` either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.
If you're building websites that use `TemplateHTMLRenderer` along with other renderer classes, you should consider listing `TemplateHTMLRenderer` as the first class in the `renderer_classes` list, so that it will be prioritised first even for browsers that send poorly formed `ACCEPT:` headers.
@@ -205,7 +205,7 @@ An example of a view that uses `TemplateHTMLRenderer`:
@api_view(('GET',))
@renderer_classes((StaticHTMLRenderer,))
- def simple_html_view(request):
+ def simple_html_view(request):
data = 'Hello, world
'
return Response(data)
@@ -300,7 +300,7 @@ The following is an example plaintext renderer that will return a response with
class PlainTextRenderer(renderers.BaseRenderer):
media_type = 'text/plain'
format = 'txt'
-
+
def render(self, data, media_type=None, renderer_context=None):
return data.encode(self.charset)
@@ -340,7 +340,7 @@ You can do some pretty flexible things using REST framework's renderers. Some e
* Provide either flat or nested representations from the same endpoint, depending on the requested media type.
* Serve both regular HTML webpages, and JSON based API responses from the same endpoints.
* Specify multiple types of HTML representation for API clients to use.
-* Underspecify a renderer's media type, such as using `media_type = 'image/*'`, and use the `Accept` header to vary the encoding of the response.
+* Underspecify a renderer's media type, such as using `media_type = 'image/*'`, and use the `Accept` header to vary the encoding of the response.
## Varying behaviour by media type
diff --git a/docs/api-guide/requests.md b/docs/api-guide/requests.md
index 87425ed1..8713fa2a 100644
--- a/docs/api-guide/requests.md
+++ b/docs/api-guide/requests.md
@@ -1,4 +1,4 @@
-
+source: request.py
# Requests
@@ -105,7 +105,7 @@ REST framework supports a few browser enhancements such as browser-based `PUT`,
Browser-based `PUT`, `PATCH` and `DELETE` forms are transparently supported.
-For more information see the [browser enhancements documentation].
+For more information see the [browser enhancements documentation].
## .content_type
@@ -115,7 +115,7 @@ You won't typically need to directly access the request's content type, as you'l
If you do need to access the content type of the request you should use the `.content_type` property in preference to using `request.META.get('HTTP_CONTENT_TYPE')`, as it provides transparent support for browser-based non-form content.
-For more information see the [browser enhancements documentation].
+For more information see the [browser enhancements documentation].
## .stream
@@ -125,7 +125,7 @@ You won't typically need to directly access the request's content, as you'll nor
If you do need to access the raw content directly, you should use the `.stream` property in preference to using `request.content`, as it provides transparent support for browser-based non-form content.
-For more information see the [browser enhancements documentation].
+For more information see the [browser enhancements documentation].
---
diff --git a/docs/api-guide/responses.md b/docs/api-guide/responses.md
index 5a42aa92..97f31271 100644
--- a/docs/api-guide/responses.md
+++ b/docs/api-guide/responses.md
@@ -1,4 +1,4 @@
-
+source: response.py
# Responses
@@ -90,6 +90,6 @@ The `Response` class extends `SimpleTemplateResponse`, and all the usual attribu
As with any other `TemplateResponse`, this method is called to render the serialized data of the response into the final response content. When `.render()` is called, the response content will be set to the result of calling the `.render(data, accepted_media_type, renderer_context)` method on the `accepted_renderer` instance.
You won't typically need to call `.render()` yourself, as it's handled by Django's standard response cycle.
-
+
[cite]: https://docs.djangoproject.com/en/dev/ref/template-response/
[statuscodes]: status-codes.md
diff --git a/docs/api-guide/reverse.md b/docs/api-guide/reverse.md
index 383eca4c..71fb83f9 100644
--- a/docs/api-guide/reverse.md
+++ b/docs/api-guide/reverse.md
@@ -1,4 +1,4 @@
-
+source: reverse.py
# Returning URLs
@@ -30,7 +30,7 @@ You should **include the request as a keyword argument** to the function, for ex
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 = now().year
diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md
index 61a476b8..080230fa 100644
--- a/docs/api-guide/routers.md
+++ b/docs/api-guide/routers.md
@@ -1,4 +1,4 @@
-
+source: routers.py
# Routers
@@ -56,10 +56,10 @@ For example, given a method like this on the `UserViewSet` class:
from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import detail_route
-
+
class UserViewSet(ModelViewSet):
...
-
+
@detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
...
@@ -228,7 +228,7 @@ For another example of setting the `.routes` attribute, see the source code for
## 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 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.
+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.
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index eeeffa13..2d0ff79a 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -1,4 +1,4 @@
-
+source: serializers.py
# Serializers
@@ -21,7 +21,7 @@ Let's start by creating a simple object we can use for example purposes:
self.email = email
self.content = content
self.created = created or datetime.datetime.now()
-
+
comment = Comment(email='leila@example.com', content='foo bar')
We'll declare a serializer that we can use to serialize and deserialize `Comment` objects.
@@ -45,7 +45,7 @@ Declaring a serializer looks very similar to declaring a form:
instance.content = attrs.get('content', instance.content)
instance.created = attrs.get('created', instance.created)
return instance
- return Comment(**attrs)
+ return Comment(**attrs)
The first part of serializer class defines the fields that get serialized/deserialized. The `restore_object` method defines how fully fledged instances get created when deserializing data.
@@ -83,8 +83,8 @@ If you need to customize the serialized value of a particular field, you can do
These methods are essentially the reverse of `validate_` (see *Validation* below.)
## Deserializing objects
-
-Deserialization is similar. First we parse a stream 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
@@ -174,7 +174,7 @@ To save the deserialized objects created by a serializer, call the `.save()` met
The default behavior of the method is to simply call `.save()` on the deserialized object instance. You can override the default save behaviour by overriding the `.save_object(obj)` method on the serializer class.
-The generic views provided by REST framework call the `.save()` method when updating or creating entities.
+The generic views provided by REST framework call the `.save()` method when updating or creating entities.
## Dealing with nested objects
@@ -288,12 +288,12 @@ By default the serializer class will use the `id` key on the incoming data to de
slug = serializers.CharField(max_length=100)
created = serializers.DateTimeField()
... # Various other fields
-
+
def get_identity(self, data):
"""
This hook is required for bulk update.
We need to override the default, to use the slug as the identity.
-
+
Note that the data has not yet been validated at this point,
so we need to deal gracefully with incorrect datatypes.
"""
@@ -361,7 +361,7 @@ The `depth` option should be set to an integer value that indicates the depth of
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
+## 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:
@@ -371,9 +371,9 @@ You may wish to specify multiple fields as read-only. Instead of adding each fi
fields = ('id', 'account_name', 'users', 'created')
read_only_fields = ('account_name',)
-Model fields which have `editable=False` set, and `AutoField` fields will be set to read-only by default, and do not need to be added to the `read_only_fields` option.
+Model fields which have `editable=False` set, and `AutoField` fields will be set to read-only by default, and do not need to be added to the `read_only_fields` option.
-## Specifying which fields should be write-only
+## Specifying which fields should be write-only
You may wish to specify multiple fields as write-only. Instead of adding each field explicitly with the `write_only=True` attribute, you may use the `write_only_fields` Meta option, like so:
@@ -387,12 +387,12 @@ You may wish to specify multiple fields as write-only. Instead of adding each f
"""
Instantiate a new User instance.
"""
- assert instance is None, 'Cannot update users with CreateUserSerializer'
+ assert instance is None, 'Cannot update users with CreateUserSerializer'
user = User(email=attrs['email'], username=attrs['username'])
user.set_password(attrs['password'])
return user
-
-## Specifying fields explicitly
+
+## Specifying fields explicitly
You can add extra fields to a `ModelSerializer` or override the default fields by declaring fields on the class, just as you would for a `Serializer` class.
@@ -524,10 +524,10 @@ For example, if you wanted to be able to set which fields should be used by a se
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
-
+
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
-
+
if fields:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
@@ -550,7 +550,7 @@ This would then allow you to do the following:
## Customising the default fields
-The `field_mapping` attribute is a dictionary that maps model classes to serializer classes. Overriding the attribute will let you set a different set of default serializer classes.
+The `field_mapping` attribute is a dictionary that maps model classes to serializer classes. Overriding the attribute will let you set a different set of default serializer classes.
For more advanced customization than simply changing the default serializer class you can override various `get__field` methods. Doing so will allow you to customize the arguments that each serializer field is initialized with. Each of these methods may either return a field or serializer instance, or `None`.
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 96d715ea..0aa4b6a9 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -1,4 +1,4 @@
-
+source: settings.py
# Settings
diff --git a/docs/api-guide/status-codes.md b/docs/api-guide/status-codes.md
index 64c46434..d81e092c 100644
--- a/docs/api-guide/status-codes.md
+++ b/docs/api-guide/status-codes.md
@@ -1,4 +1,4 @@
-
+source: status.py
# Status Codes
@@ -27,7 +27,7 @@ The module also includes a set of helper functions for testing if a status code
url = reverse('index')
response = self.client.get(url)
self.assertTrue(status.is_success(response.status_code))
-
+
For more information on proper usage of HTTP status codes see [RFC 2616][rfc2616]
and [RFC 6585][rfc6585].
@@ -51,7 +51,7 @@ This class of status code indicates that the client's request was successfully r
HTTP_205_RESET_CONTENT
HTTP_206_PARTIAL_CONTENT
-## Redirection - 3xx
+## Redirection - 3xx
This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request.
diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md
index 72c33961..d059fdab 100644
--- a/docs/api-guide/testing.md
+++ b/docs/api-guide/testing.md
@@ -1,4 +1,4 @@
-
+source: test.py
# Testing
@@ -170,7 +170,7 @@ This can be a useful shortcut if you're testing the API but don't want to have t
To unauthenticate subsequent requests, call `force_authenticate` setting the user and/or token to `None`.
- client.force_authenticate(user=None)
+ client.force_authenticate(user=None)
## CSRF validation
@@ -197,7 +197,7 @@ You can use any of REST framework's test case classes as you would for the regul
from django.core.urlresolvers import reverse
from rest_framework import status
- from rest_framework.test import APITestCase
+ from rest_framework.test import APITestCase
class AccountTests(APITestCase):
def test_create_account(self):
diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md
index 147c16ff..3f668867 100644
--- a/docs/api-guide/throttling.md
+++ b/docs/api-guide/throttling.md
@@ -1,4 +1,4 @@
-
+source: throttling.py
# Throttling
@@ -83,7 +83,7 @@ The throttle classes provided by REST framework use Django's cache backend. You
If you need to use a cache other than `'default'`, you can do so by creating a custom throttle class and setting the `cache` attribute. For example:
class CustomAnonRateThrottle(AnonRateThrottle):
- cache = get_cache('alternate')
+ cache = get_cache('alternate')
You'll need to remember to also set your custom throttle class in the `'DEFAULT_THROTTLE_CLASSES'` settings key, or using the `throttle_classes` view attribute.
@@ -147,15 +147,15 @@ For example, given the following views...
class ContactListView(APIView):
throttle_scope = 'contacts'
...
-
+
class ContactDetailView(ApiView):
throttle_scope = 'contacts'
...
- class UploadView(APIView):
+ class UploadView(APIView):
throttle_scope = 'uploads'
...
-
+
...and the following settings.
REST_FRAMEWORK = {
diff --git a/docs/api-guide/views.md b/docs/api-guide/views.md
index 194a7a6b..31c62682 100644
--- a/docs/api-guide/views.md
+++ b/docs/api-guide/views.md
@@ -1,4 +1,5 @@
-
+source: decorators.py
+ views.py
# Class Based Views
@@ -26,7 +27,7 @@ For example:
class ListUsers(APIView):
"""
View to list all users in the system.
-
+
* Requires token authentication.
* Only admin users are able to access this view.
"""
@@ -54,7 +55,7 @@ The following attributes control the pluggable aspects of API views.
### .permission_classes
-### .content_negotiation_class
+### .content_negotiation_class
## API policy instantiation methods
diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md
index 9030e3ee..9249d875 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -1,4 +1,4 @@
-
+source: viewsets.py
# ViewSets
--
cgit v1.2.3