diff --git a/.travis.yml b/.travis.yml
index 9dd587be9..6191e7e26 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,7 @@ sudo: false
env:
- TOX_ENV=py27-flake8
+ - TOX_ENV=py27-docs
- TOX_ENV=py34-django17
- TOX_ENV=py33-django17
- TOX_ENV=py32-django17
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1b1995348..698029959 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -101,15 +101,15 @@ There are many great markdown editors that make working with the documentation r
## Building the documentation
-To build the documentation, simply run the `mkdocs.py` script.
+To build the documentation, install MkDocs with `pip install mkdocs` and then run the following command.
- ./mkdocs.py
+ mkdocs build
This will build the html output into the `html` directory.
-You can build the documentation and open a preview in a browser window by using the `-p` flag.
+You can build the documentation and open a preview in a browser window by using the `serve` command.
- ./mkdocs.py -p
+ mkdocs serve
## Language style
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index 01774c10d..b04858e39 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 94dd59cac..bc3b09fb7 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 e61dcfa90..8e0b1958e 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 292a51d89..354ec9662 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 cfeb43349..83977048f 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 76a3367b0..20c1e9952 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 49a5e58f0..648ece827 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 e57aed1a9..9b7086c54 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 72a4af643..42d77b223 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 446e362e1..f068f0f72 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 d03a75ae5..ad981b2bb 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 db7436c23..035ec1d27 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 87425ed1b..8713fa2a6 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 5a42aa923..97f312710 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 383eca4ce..71fb83f9e 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 61a476b8b..080230faf 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 eeeffa136..2d0ff79a4 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 96d715ea2..0aa4b6a97 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 64c464349..d81e092c5 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 72c339613..d059fdab5 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 147c16ff7..3f668867c 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 194a7a6b3..31c62682f 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 9030e3ee0..9249d8756 100644
--- a/docs/api-guide/viewsets.md
+++ b/docs/api-guide/viewsets.md
@@ -1,4 +1,4 @@
-
+source: viewsets.py
# ViewSets
diff --git a/docs/css/default.css b/docs/css/default.css
index 7f3acfed2..8c9cd5363 100644
--- a/docs/css/default.css
+++ b/docs/css/default.css
@@ -181,7 +181,7 @@ body{
}
.navbar .navbar-inner .nav li, .navbar .navbar-inner .nav li a, .navbar .navbar-inner .brand{
- color: white;
+ color: white;
}
.nav-list > .active > a, .navbar .navbar-inner .nav li a:hover {
@@ -190,8 +190,20 @@ body{
}
.navbar .navbar-inner .dropdown-menu li a, .navbar .navbar-inner .dropdown-menu li{
- color: #A30000;
+ color: #A30000;
}
+
+.dropdown-menu .active > a,
+.dropdown-menu .active > a:hover {
+ background-image: none;
+}
+
+.navbar-inverse .nav .dropdown .active > a,
+.navbar-inverse .nav .dropdown .active > a:hover,
+.navbar-inverse .nav .dropdown .active > a:focus {
+ background-color: #eeeeee;
+}
+
.navbar .navbar-inner .dropdown-menu li a:hover{
background: #eeeeee;
color: #c20000;
diff --git a/docs/index.md b/docs/index.md
index 6288efa3c..ca10befe3 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -26,9 +26,6 @@
-
Django REST framework is a powerful and flexible toolkit that makes it easy to build Web APIs.
diff --git a/docs/requirements.txt b/docs/requirements.txt
deleted file mode 100644
index a91fb9785..000000000
--- a/docs/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-markdown>=2.1.0
diff --git a/docs/template.html b/docs/template.html
deleted file mode 100644
index f36cffc6d..000000000
--- a/docs/template.html
+++ /dev/null
@@ -1,239 +0,0 @@
-
-
-
-
- {{ title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/topics/2.2-announcement.md b/docs/topics/2.2-announcement.md
index a997c7829..1df52cff2 100644
--- a/docs/topics/2.2-announcement.md
+++ b/docs/topics/2.2-announcement.md
@@ -42,7 +42,7 @@ The 2.2 release makes a few changes to the API, in order to make it more consist
The `ManyRelatedField()` style is being deprecated in favor of a new `RelatedField(many=True)` syntax.
-For example, if a user is associated with multiple questions, which we want to represent using a primary key relationship, we might use something like the following:
+For example, if a user is associated with multiple questions, which we want to represent using a primary key relationship, we might use something like the following:
class UserSerializer(serializers.HyperlinkedModelSerializer):
questions = serializers.PrimaryKeyRelatedField(many=True)
@@ -58,10 +58,10 @@ The change also applies to serializers. If you have a nested serializer, you sh
class Meta:
model = Track
fields = ('name', 'duration')
-
+
class AlbumSerializer(serializer.ModelSerializer):
tracks = TrackSerializer(many=True)
-
+
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
@@ -87,7 +87,7 @@ For example, is a user account has an optional foreign key to a company, that yo
This is in line both with the rest of the serializer fields API, and with Django's `Form` and `ModelForm` API.
-Using `required` throughout the serializers API means you won't need to consider if a particular field should take `blank` or `null` arguments instead of `required`, and also means there will be more consistent behavior for how fields are treated when they are not present in the incoming data.
+Using `required` throughout the serializers API means you won't need to consider if a particular field should take `blank` or `null` arguments instead of `required`, and also means there will be more consistent behavior for how fields are treated when they are not present in the incoming data.
The `null=True` argument will continue to function, and will imply `required=False`, but will raise a `PendingDeprecationWarning`.
diff --git a/docs/topics/2.3-announcement.md b/docs/topics/2.3-announcement.md
index 7c800afa0..9c9f3e9f6 100644
--- a/docs/topics/2.3-announcement.md
+++ b/docs/topics/2.3-announcement.md
@@ -27,7 +27,7 @@ As an example of just how simple REST framework APIs can now be, here's an API w
class GroupViewSet(viewsets.ModelViewSet):
model = Group
-
+
# Routers provide an easy way of automatically determining the URL conf
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
@@ -197,13 +197,13 @@ Usage of the old-style attributes continues to be supported, but will raise a `P
For most cases APIs using model fields will behave as previously, however if you are using a custom renderer, not provided by REST framework, then you may now need to add support for rendering `Decimal` instances to your renderer implementation.
-## ModelSerializers and reverse relationships
+## ModelSerializers and reverse relationships
The support for adding reverse relationships to the `fields` option on a `ModelSerializer` class means that the `get_related_field` and `get_nested_field` method signatures have now changed.
In the unlikely event that you're providing a custom serializer class, and implementing these methods you should note the new call signature for both methods is now `(self, model_field, related_model, to_many)`. For reverse relationships `model_field` will be `None`.
-The old-style signature will continue to function but will raise a `PendingDeprecationWarning`.
+The old-style signature will continue to function but will raise a `PendingDeprecationWarning`.
## View names and descriptions
@@ -211,7 +211,7 @@ The mechanics of how the names and descriptions used in the browseable API are g
If you've been customizing this behavior, for example perhaps to use `rst` markup for the browseable API, then you'll need to take a look at the implementation to see what updates you need to make.
-Note that the relevant methods have always been private APIs, and the docstrings called them out as intended to be deprecated.
+Note that the relevant methods have always been private APIs, and the docstrings called them out as intended to be deprecated.
---
diff --git a/docs/topics/contributing.md b/docs/topics/contributing.md
index 52f6e287d..c7991a0fe 100644
--- a/docs/topics/contributing.md
+++ b/docs/topics/contributing.md
@@ -135,15 +135,15 @@ There are many great Markdown editors that make working with the documentation r
## Building the documentation
-To build the documentation, simply run the `mkdocs.py` script.
+To build the documentation, install MkDocs with `pip install mkdocs` and then run the following command.
- ./mkdocs.py
+ mkdocs build
This will build the html output into the `html` directory.
-You can build the documentation and open a preview in a browser window by using the `-p` flag.
+You can build the documentation and open a preview in a browser window by using the `serve` command.
- ./mkdocs.py -p
+ mkdocs serve
## Language style
diff --git a/docs/topics/documenting-your-api.md b/docs/topics/documenting-your-api.md
index e20f97122..d65e251f1 100644
--- a/docs/topics/documenting-your-api.md
+++ b/docs/topics/documenting-your-api.md
@@ -54,7 +54,7 @@ The title that is used in the browsable API is generated from the view class nam
For example, the view `UserListView`, will be named `User List` when presented in the browsable API.
-When working with viewsets, an appropriate suffix is appended to each generated view. For example, the view set `UserViewSet` will generate views named `User List` and `User Instance`.
+When working with viewsets, an appropriate suffix is appended to each generated view. For example, the view set `UserViewSet` will generate views named `User List` and `User Instance`.
#### Setting the description
@@ -65,9 +65,9 @@ If the python `markdown` library is installed, then [markdown syntax][markdown]
class AccountListView(views.APIView):
"""
Returns a list of all **active** accounts in the system.
-
+
For more details on how accounts are activated please [see here][ref].
-
+
[ref]: http://example.com/activating-accounts
"""
@@ -84,7 +84,7 @@ You can modify the response behavior to `OPTIONS` requests by overriding the `me
def metadata(self, request):
"""
Don't include the view description in OPTIONS responses.
- """
+ """
data = super(ExampleView, self).metadata(request)
data.pop('description')
return data
diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md
index 7d1f6d0eb..e8bad95be 100644
--- a/docs/topics/kickstarter-announcement.md
+++ b/docs/topics/kickstarter-announcement.md
@@ -160,4 +160,4 @@ The following individuals made a significant financial contribution to the devel
### Supporters
-There were also almost 300 further individuals choosing to help fund the project at other levels or choosing to give anonymously. Again, thank you, thank you, thank you!
\ No newline at end of file
+There were also almost 300 further individuals choosing to help fund the project at other levels or choosing to give anonymously. Again, thank you, thank you, thank you!
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 88780c3fb..9fca949ab 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -63,7 +63,7 @@ You can determine your currently installed version using `pip freeze`:
* Bugfix: Fix migration in `authtoken` application.
* Bugfix: Allow selection of integer keys in nested choices.
* Bugfix: Return `None` instead of `'None'` in `CharField` with `allow_none=True`.
-* Bugfix: Ensure custom model fields map to equivelent serializer fields more reliably.
+* Bugfix: Ensure custom model fields map to equivelent serializer fields more reliably.
* Bugfix: `DjangoFilterBackend` no longer quietly changes queryset ordering.
### 2.4.2
diff --git a/docs/topics/rest-framework-2-announcement.md b/docs/topics/rest-framework-2-announcement.md
index f1060d90b..a7746932e 100644
--- a/docs/topics/rest-framework-2-announcement.md
+++ b/docs/topics/rest-framework-2-announcement.md
@@ -8,7 +8,7 @@ What it is, and why you should care.
---
-**Announcement:** REST framework 2 released - Tue 30th Oct 2012
+**Announcement:** REST framework 2 released - Tue 30th Oct 2012
---
@@ -37,7 +37,7 @@ REST framework 2 includes a totally re-worked serialization engine, that was ini
* A declarative serialization API, that mirrors Django's `Forms`/`ModelForms` API.
* Structural concerns are decoupled from encoding concerns.
* Able to support rendering and parsing to many formats, including both machine-readable representations and HTML forms.
-* Validation that can be mapped to obvious and comprehensive error responses.
+* Validation that can be mapped to obvious and comprehensive error responses.
* Serializers that support both nested, flat, and partially-nested representations.
* Relationships that can be expressed as primary keys, hyperlinks, slug fields, and other custom representations.
diff --git a/docs/topics/writable-nested-serializers.md b/docs/topics/writable-nested-serializers.md
index abc6a82f7..ed614bd24 100644
--- a/docs/topics/writable-nested-serializers.md
+++ b/docs/topics/writable-nested-serializers.md
@@ -8,7 +8,7 @@ Although flat data structures serve to properly delineate between the individual
Nested data structures are easy enough to work with if they're read-only - simply nest your serializer classes and you're good to go. However, there are a few more subtleties to using writable nested serializers, due to the dependencies between the various model instances, and the need to save or delete multiple instances in a single action.
-## One-to-many data structures
+## One-to-many data structures
*Example of a **read-only** nested serializer. Nothing complex to worry about here.*
@@ -16,10 +16,10 @@ Nested data structures are easy enough to work with if they're read-only - simpl
class Meta:
model = ToDoItem
fields = ('text', 'is_completed')
-
+
class ToDoListSerializer(serializers.ModelSerializer):
items = ToDoItemSerializer(many=True, read_only=True)
-
+
class Meta:
model = ToDoList
fields = ('title', 'items')
@@ -31,7 +31,7 @@ Some example output from our serializer.
'items': {
{'text': 'Compile playlist', 'is_completed': True},
{'text': 'Send invites', 'is_completed': False},
- {'text': 'Clean house', 'is_completed': False}
+ {'text': 'Clean house', 'is_completed': False}
}
}
@@ -44,4 +44,4 @@ Let's take a look at updating our nested one-to-many data structure.
### Making PATCH requests
-[cite]: http://jsonapi.org/format/#url-based-json-api
\ No newline at end of file
+[cite]: http://jsonapi.org/format/#url-based-json-api
diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md
index db5b9ea7b..f9027b688 100644
--- a/docs/tutorial/1-serialization.md
+++ b/docs/tutorial/1-serialization.md
@@ -134,7 +134,7 @@ A serializer class is very similar to a Django `Form` class, and includes simila
The field flags can also control how the serializer should be displayed in certain circumstances, such as when rendering to HTML. The `style={'type': 'textarea'}` flag above is equivelent to using `widget=widgets.Textarea` on a Django `Form` class. This is particularly useful for controlling how the browsable API should be displayed, as we'll see later in the tutorial.
-We can actually also save ourselves some time by using the `ModelSerializer` class, as we'll see later, but for now we'll keep our serializer definition explicit.
+We can actually also save ourselves some time by using the `ModelSerializer` class, as we'll see later, but for now we'll keep our serializer definition explicit.
## Working with Serializers
diff --git a/docs/404.html b/docs_theme/404.html
similarity index 60%
rename from docs/404.html
rename to docs_theme/404.html
index 864247e78..44993e37d 100644
--- a/docs/404.html
+++ b/docs_theme/404.html
@@ -1,50 +1,54 @@
-
-
- Django REST framework - 404 - Page not found
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Django REST framework - 404 - Page not found
+
+
+
+
+
-
-
+
+
+
+
+
-
+
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18852272-2']);
- _gaq.push(['_trackPageview']);
+
+
-
-
-
+