aboutsummaryrefslogtreecommitdiffstats
path: root/docs/api-guide
diff options
context:
space:
mode:
Diffstat (limited to 'docs/api-guide')
-rw-r--r--docs/api-guide/authentication.md38
-rw-r--r--docs/api-guide/fields.md70
-rw-r--r--docs/api-guide/filtering.md178
-rw-r--r--docs/api-guide/generic-views.md36
-rw-r--r--docs/api-guide/pagination.md33
-rw-r--r--docs/api-guide/parsers.md1
-rw-r--r--docs/api-guide/serializers.md15
-rw-r--r--docs/api-guide/settings.md22
-rw-r--r--docs/api-guide/views.md4
9 files changed, 380 insertions, 17 deletions
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index 3137b9d4..43fc15d2 100644
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -68,7 +68,7 @@ This policy uses [HTTP Basic Authentication][basicauth], signed against a user's
If successfully authenticated, `BasicAuthentication` provides the following credentials.
-* `request.user` will be a `django.contrib.auth.models.User` instance.
+* `request.user` will be a Django `User` instance.
* `request.auth` will be `None`.
**Note:** If you use `BasicAuthentication` in production you must ensure that your API is only available over `https` only. You should also ensure that your API clients will always re-request the username and password at login, and will never store those details to persistent storage.
@@ -92,19 +92,49 @@ For clients to authenticate, the token key should be included in the `Authorizat
If successfully authenticated, `TokenAuthentication` provides the following credentials.
-* `request.user` will be a `django.contrib.auth.models.User` instance.
+* `request.user` will be a Django `User` instance.
* `request.auth` will be a `rest_framework.tokenauth.models.BasicToken` instance.
**Note:** If you use `TokenAuthentication` in production you must ensure that your API is only available over `https` only.
+If you want every user to have an automatically generated Token, you can simply catch the User's `post_save` signal.
+
+ @receiver(post_save, sender=User)
+ def create_auth_token(sender, instance=None, created=False, **kwargs):
+ if created:
+ Token.objects.create(user=instance)
+
+If you've already created some users, you can generate tokens for all existing users like this:
+
+ from django.contrib.auth.models import User
+ from rest_framework.authtoken.models import Token
+
+ for user in User.objects.all():
+ Token.objects.get_or_create(user=user)
+
+When using `TokenAuthentication`, you may want to provide a mechanism for clients to obtain a token given the username and password.
+REST framework provides a built-in view to provide this behavior. To use it, add the `obtain_auth_token` view to your URLconf:
+
+ urlpatterns += patterns('',
+ url(r'^api-token-auth/', 'rest_framework.authtoken.views.obtain_auth_token')
+ )
+
+Note that the URL part of the pattern can be whatever you want to use.
+
+The `obtain_auth_token` view will return a JSON response when valid `username` and `password` fields are POSTed to the view using form data or JSON:
+
+ { 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
+
+<!--
## OAuthAuthentication
This policy uses the [OAuth 2.0][oauth] protocol to authenticate requests. OAuth is appropriate for server-server setups, such as when you want to allow a third-party service to access your API on a user's behalf.
If successfully authenticated, `OAuthAuthentication` provides the following credentials.
-* `request.user` will be a `django.contrib.auth.models.User` instance.
+* `request.user` will be a Django `User` instance.
* `request.auth` will be a `rest_framework.models.OAuthToken` instance.
+-->
## SessionAuthentication
@@ -112,7 +142,7 @@ This policy uses Django's default session backend for authentication. Session a
If successfully authenticated, `SessionAuthentication` provides the following credentials.
-* `request.user` will be a `django.contrib.auth.models.User` instance.
+* `request.user` will be a Django `User` instance.
* `request.auth` will be `None`.
# Custom authentication
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index 0485b158..1d4c34cb 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -131,6 +131,18 @@ or `django.db.models.fields.TextField`.
**Signature:** `CharField(max_length=None, min_length=None)`
+## URLField
+
+Corresponds to `django.db.models.fields.URLField`. Uses Django's `django.core.validators.URLValidator` for validation.
+
+**Signature:** `CharField(max_length=200, min_length=None)`
+
+## SlugField
+
+Corresponds to `django.db.models.fields.SlugField`.
+
+**Signature:** `CharField(max_length=50, min_length=None)`
+
## ChoiceField
A field that can accept a value out of a limited set of choices.
@@ -141,6 +153,16 @@ A text representation, validates the text to be a valid e-mail address.
Corresponds to `django.db.models.fields.EmailField`
+## RegexField
+
+A text representation, that validates the given value matches against a certain regular expression.
+
+Uses Django's `django.core.validators.RegexValidator` for validation.
+
+Corresponds to `django.forms.fields.RegexField`
+
+**Signature:** `RegexField(regex, max_length=None, min_length=None)`
+
## DateField
A date representation.
@@ -165,6 +187,33 @@ A floating point representation.
Corresponds to `django.db.models.fields.FloatField`.
+## FileField
+
+A file representation. Performs Django's standard FileField validation.
+
+Corresponds to `django.forms.fields.FileField`.
+
+**Signature:** `FileField(max_length=None, allow_empty_file=False)`
+
+ - `max_length` designates the maximum length for the file name.
+
+ - `allow_empty_file` designates if empty files are allowed.
+
+## ImageField
+
+An image representation.
+
+Corresponds to `django.forms.fields.ImageField`.
+
+Requires the `PIL` package.
+
+Signature and validation is the same as with `FileField`.
+
+---
+
+**Note:** `FileFields` and `ImageFields` are only suitable for use with MultiPartParser, since eg json doesn't support file uploads.
+Django's regular [FILE_UPLOAD_HANDLERS] are used for handling uploaded files.
+
---
# Relational Fields
@@ -285,4 +334,25 @@ This field is always read-only.
* `pk_url_kwarg` - The named url parameter for the pk field lookup. Default is `pk`.
* `slug_url_kwarg` - The named url parameter for the slug field lookup. Default is to use the same value as given for `slug_field`.
+# Other Fields
+
+## SerializerMethodField
+
+This is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object. The field's constructor accepts a single argument, which is the name of the method on the serializer to be called. The method should accept a single argument (in addition to `self`), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:
+
+ from rest_framework import serializers
+ from django.contrib.auth.models import User
+ from django.utils.timezone import now
+
+ class UserSerializer(serializers.ModelSerializer):
+
+ days_since_joined = serializers.SerializerMethodField('get_days_since_joined')
+
+ class Meta:
+ model = User
+
+ def get_days_since_joined(self, obj):
+ return (now() - obj.date_joined).days
+
[cite]: http://www.python.org/dev/peps/pep-0020/
+[FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS
diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md
new file mode 100644
index 00000000..53ea7cbc
--- /dev/null
+++ b/docs/api-guide/filtering.md
@@ -0,0 +1,178 @@
+<a class="github" href="filters.py"></a>
+
+# Filtering
+
+> The root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects.
+>
+> &mdash; [Django documentation][cite]
+
+The default behavior of REST framework's generic list views is to return the entire queryset for a model manager. Often you will want your API to restrict the items that are returned by the queryset.
+
+The simplest way to filter the queryset of any view that subclasses `MultipleObjectAPIView` is to override the `.get_queryset()` method.
+
+Overriding this method allows you to customize the queryset returned by the view in a number of different ways.
+
+## Filtering against the current user
+
+You might want to filter the queryset to ensure that only results relevant to the currently authenticated user making the request are returned.
+
+You can do so by filtering based on the value of `request.user`.
+
+For example:
+
+ class PurchaseList(generics.ListAPIView)
+ model = Purchase
+ serializer_class = PurchaseSerializer
+
+ def get_queryset(self):
+ """
+ This view should return a list of all the purchases
+ for the currently authenticated user.
+ """
+ user = self.request.user
+ return Purchase.objects.filter(purchaser=user)
+
+
+## Filtering against 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:
+
+ url('^purchases/(?P<username>.+)/$', PurchaseList.as_view()),
+
+You could then write a view that returned a purchase queryset filtered by the username portion of the URL:
+
+ class PurchaseList(generics.ListAPIView)
+ model = Purchase
+ serializer_class = PurchaseSerializer
+
+ def get_queryset(self):
+ """
+ This view should return a list of all the purchases for
+ the user as determined by the username portion of the URL.
+ """
+ username = self.kwargs['username']
+ return Purchase.objects.filter(purchaser__username=username)
+
+## 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.
+
+We can override `.get_queryset()` to deal with URLs such as `http://example.com/api/purchases?username=denvercoder9`, and filter the queryset only if the `username` parameter is included in the URL:
+
+ class PurchaseList(generics.ListAPIView)
+ model = Purchase
+ serializer_class = PurchaseSerializer
+
+ def get_queryset(self):
+ """
+ Optionally restricts the returned purchases to a given user,
+ by filtering against a `username` query parameter in the URL.
+ """
+ queryset = Purchase.objects.all()
+ username = self.request.QUERY_PARAMS.get('username', None)
+ if username is not None:
+ queryset = queryset.filter(purchaser__username=username)
+ return queryset
+
+---
+
+# Generic Filtering
+
+As well as being able to override the default queryset, REST framework also includes support for generic filtering backends that allow you to easily construct complex filters that can be specified by the client using query parameters.
+
+REST framework supports pluggable backends to implement filtering, and provides an implementation which uses the [django-filter] package.
+
+To use REST framework's filtering backend, first install `django-filter`.
+
+ pip install django-filter
+
+You must also set the filter backend to `DjangoFilterBackend` in your settings:
+
+ REST_FRAMEWORK = {
+ 'FILTER_BACKEND': 'rest_framework.filters.DjangoFilterBackend'
+ }
+
+
+## Specifying filter fields
+
+If all you need is simple equality-based filtering, you can set a `filter_fields` attribute on the view, listing the set of fields you wish to filter against.
+
+ class ProductList(generics.ListAPIView):
+ model = Product
+ serializer_class = ProductSerializer
+ filter_fields = ('category', 'in_stock')
+
+This will automatically create a `FilterSet` class for the given fields, and will allow you to make requests such as:
+
+ http://example.com/api/products?category=clothing&in_stock=True
+
+## Specifying a FilterSet
+
+For more advanced filtering requirements you can specify a `FilterSet` class that should be used by the view. For example:
+
+ class ProductFilter(django_filters.FilterSet):
+ min_price = django_filters.NumberFilter(lookup_type='gte')
+ max_price = django_filters.NumberFilter(lookup_type='lte')
+ class Meta:
+ model = Product
+ fields = ['category', 'in_stock', 'min_price', 'max_price']
+
+ class ProductList(generics.ListAPIView):
+ model = Product
+ serializer_class = ProductSerializer
+ filter_class = ProductFilter
+
+Which will allow you to make requests such as:
+
+ http://example.com/api/products?category=clothing&max_price=10.00
+
+For more details on using filter sets see the [django-filter documentation][django-filter-docs].
+
+---
+
+**Hints & Tips**
+
+* By default filtering is not enabled. If you want to use `DjangoFilterBackend` remember to make sure it is installed by using the `'FILTER_BACKEND'` 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].)
+* `django-filter` supports filtering across relationships, using Django's double-underscore syntax.
+
+---
+
+## 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):
+ """
+ Return a list of all the products that the authenticated
+ user has ever purchased, with optional filtering.
+ """
+ model = Product
+ serializer_class = ProductSerializer
+ filter_class = ProductFilter
+
+ def get_queryset(self):
+ user = self.request.user
+ return user.purchase_set.all()
+---
+
+# Custom generic filtering
+
+You can also provide your own generic filtering backend, or write an installable app for other developers to use.
+
+To do so override `BaseFilterBackend`, and override the `.filter_queryset(self, request, queryset, view)` method. The method should return a new, filtered queryset.
+
+To install the filter backend, set the `'FILTER_BACKEND'` key in your `'REST_FRAMEWORK'` setting, using the dotted import path of the filter backend class.
+
+For example:
+
+ REST_FRAMEWORK = {
+ 'FILTER_BACKEND': 'custom_filters.CustomFilterBackend'
+ }
+
+[cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters
+[django-filter]: https://github.com/alex/django-filter
+[django-filter-docs]: https://django-filter.readthedocs.org/en/latest/index.html
+[nullbooleanselect]: https://github.com/django/django/blob/master/django/forms/widgets.py \ No newline at end of file
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 360ef1a2..428323b8 100644
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -123,18 +123,36 @@ Each of the generic views provided is built by combining one of the base views b
Extends REST framework's `APIView` class, adding support for serialization of model instances and model querysets.
+**Attributes**:
+
+* `model` - The model that should be used for this view. Used as a fallback for determining the serializer if `serializer_class` is not set, and as a fallback for determining the queryset if `queryset` is not set. Otherwise not required.
+* `serializer_class` - The serializer class that should be used for validating and deserializing input, and for serializing output. If unset, this defaults to creating a serializer class using `self.model`, with the `DEFAULT_MODEL_SERIALIZER_CLASS` setting as the base serializer class.
+
## MultipleObjectAPIView
Provides a base view for acting on a single object, by combining REST framework's `APIView`, and Django's [MultipleObjectMixin].
**See also:** ccbv.co.uk documentation for [MultipleObjectMixin][multiple-object-mixin-classy].
+**Attributes**:
+
+* `queryset` - The queryset that should be used for returning objects from this view. If unset, defaults to the default queryset manager for `self.model`.
+* `paginate_by` - The size of pages to use with paginated data. If set to `None` then pagination is turned off. If unset this uses the same value as the `PAGINATE_BY` setting, which defaults to `None`.
+* `paginate_by_param` - The name of a query parameter, which can be used by the client to overide the default page size to use for pagination. If unset this uses the same value as the `PAGINATE_BY_PARAM` setting, which defaults to `None`.
+
## SingleObjectAPIView
Provides a base view for acting on a single object, by combining REST framework's `APIView`, and Django's [SingleObjectMixin].
**See also:** ccbv.co.uk documentation for [SingleObjectMixin][single-object-mixin-classy].
+**Attributes**:
+
+* `queryset` - The queryset that should be used when retrieving an object from this view. If unset, defaults to the default queryset manager for `self.model`.
+* `pk_kwarg` - The URL kwarg that should be used to look up objects by primary key. Defaults to `'pk'`. [Can only be set to non-default on Django 1.4+]
+* `slug_kwarg` - The URL kwarg that should be used to look up objects by a slug. Defaults to `'slug'`. [Can only be set to non-default on Django 1.4+]
+* `slug_field` - The field on the model that should be used to look up objects by a slug. If used, this should typically be set to a field with `unique=True`. Defaults to `'slug'`.
+
---
# Mixins
@@ -145,30 +163,48 @@ The mixin classes provide the actions that are used to provide the basic view be
Provides a `.list(request, *args, **kwargs)` method, that implements listing a queryset.
+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` reponse, unless the `.allow_empty` attribute on the view is set to `False`, in which case it will return a `404 Not Found`.
+
Should be mixed in with [MultipleObjectAPIView].
## CreateModelMixin
Provides a `.create(request, *args, **kwargs)` method, that implements creating and saving a new model instance.
+If an object is created this returns a `201 Created` response, with a serialized representation of the object as the body of the response. If the representation contains a key named `url`, then the `Location` header of the response will be populated with that value.
+
+If the request data provided for creating the object was invalid, a `400 Bad Request` response will be returned, with the error details as the body of the response.
+
Should be mixed in with any [GenericAPIView].
## RetrieveModelMixin
Provides a `.retrieve(request, *args, **kwargs)` method, that implements returning an existing model instance in a response.
+If an object can be retrieve this returns a `200 OK` response, with a serialized representation of the object as the body of the response. Otherwise it will return a `404 Not Found`.
+
Should be mixed in with [SingleObjectAPIView].
## UpdateModelMixin
Provides a `.update(request, *args, **kwargs)` method, that implements updating and saving an existing model instance.
+If an object is updated this returns a `200 OK` response, with a serialized representation of the object as the body of the response.
+
+If an object is created, for example when making a `DELETE` request followed by a `PUT` request to the same URL, this returns a `201 Created` response, with a serialized representation of the object as the body of the response.
+
+If the request data provided for updating the object was invalid, a `400 Bad Request` response will be returned, with the error details as the body of the response.
+
Should be mixed in with [SingleObjectAPIView].
## DestroyModelMixin
Provides a `.destroy(request, *args, **kwargs)` method, that implements deletion of an existing model instance.
+If an object is deleted this returns a `204 No Content` response, otherwise it will return a `404 Not Found`.
+
Should be mixed in with [SingleObjectAPIView].
[cite]: https://docs.djangoproject.com/en/dev/ref/class-based-views/#base-vs-generic-views
diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md
index 597baba4..ab335e6e 100644
--- a/docs/api-guide/pagination.md
+++ b/docs/api-guide/pagination.md
@@ -70,33 +70,32 @@ We could now use our pagination serializer in a view like this.
# If page is not an integer, deliver first page.
users = paginator.page(1)
except EmptyPage:
- # If page is out of range (e.g. 9999), deliver last page of results.
+ # If page is out of range (e.g. 9999),
+ # deliver last page of results.
users = paginator.page(paginator.num_pages)
serializer_context = {'request': request}
- serializer = PaginatedUserSerializer(instance=users,
+ serializer = PaginatedUserSerializer(users,
context=serializer_context)
return Response(serializer.data)
## Pagination in the generic views
-The generic class based views `ListAPIView` and `ListCreateAPIView` provide pagination of the returned querysets by default. You can customise this behaviour by altering the pagination style, by modifying the default number of results, or by turning pagination off completely.
+The generic class based views `ListAPIView` and `ListCreateAPIView` provide pagination of the returned querysets by default. You can customise this behaviour by altering the pagination style, by modifying the default number of results, by allowing clients to override the page size using a query parameter, or by turning pagination off completely.
-The default pagination style may be set globally, using the `PAGINATION_SERIALIZER` and `PAGINATE_BY` settings. For example.
+The default pagination style may be set globally, using the `DEFAULT_PAGINATION_SERIALIZER_CLASS`, `PAGINATE_BY` and `PAGINATE_BY_PARAM` settings. For example.
REST_FRAMEWORK = {
- 'PAGINATION_SERIALIZER': (
- 'example_app.pagination.CustomPaginationSerializer',
- ),
- 'PAGINATE_BY': 10
+ 'PAGINATE_BY': 10,
+ 'PAGINATE_BY_PARAM': 'page_size'
}
You can also set the pagination style on a per-view basis, using the `ListAPIView` generic class-based view.
class PaginatedListView(ListAPIView):
model = ExampleModel
- pagination_serializer_class = CustomPaginationSerializer
paginate_by = 10
+ paginate_by_param = 'page_size'
For more complex requirements such as serialization that differs depending on the requested media type you can override the `.get_paginate_by()` and `.get_pagination_serializer_class()` methods.
@@ -122,4 +121,20 @@ For example, to nest a pair of links labelled 'prev' and 'next', and set the nam
results_field = 'objects'
+## Using your custom pagination serializer
+
+To have your custom pagination serializer be used by default, use the `DEFAULT_PAGINATION_SERIALIZER_CLASS` setting:
+
+ REST_FRAMEWORK = {
+ 'DEFAULT_PAGINATION_SERIALIZER_CLASS':
+ 'example_app.pagination.CustomPaginationSerializer',
+ }
+
+Alternatively, to set your custom pagination serializer on a per-view basis, use the `pagination_serializer_class` attribute on a generic class based view:
+
+ class PaginatedListView(ListAPIView):
+ model = ExampleModel
+ pagination_serializer_class = CustomPaginationSerializer
+ paginate_by = 10
+
[cite]: https://docs.djangoproject.com/en/dev/topics/pagination/
diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md
index 59f00f99..185b616c 100644
--- a/docs/api-guide/parsers.md
+++ b/docs/api-guide/parsers.md
@@ -140,6 +140,7 @@ For example:
"""
A naive raw file upload parser.
"""
+ media_type = '*/*' # Accept anything
def parse(self, stream, media_type=None, parser_context=None):
content = stream.read()
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index 0cdae1ce..19efde3c 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -34,7 +34,7 @@ Declaring a serializer looks very similar to declaring a form:
created = serializers.DateTimeField()
def restore_object(self, attrs, instance=None):
- if instance:
+ if instance is not None:
instance.title = attrs['title']
instance.content = attrs['content']
instance.created = attrs['created']
@@ -77,6 +77,10 @@ When deserializing data, we can either create a new instance, or update an exist
serializer = CommentSerializer(data=data) # Create new instance
serializer = CommentSerializer(comment, data=data) # Update `instance`
+By default, serializers must be passed values for all required fields or they will throw validation errors. You can use the `partial` argument in order to allow partial updates.
+
+ serializer = CommentSerializer(comment, data={'content': u'foo bar'}, partial=True) # Update `instance` with partial data
+
## Validation
When deserializing data, you always need to call `is_valid()` before attempting to access the deserialized object. If any validation errors occur, the `.errors` and `.non_field_errors` properties will contain the resulting error messages.
@@ -248,6 +252,15 @@ The default `ModelSerializer` uses primary keys for relationships, but you can a
The `depth` option should be set to an integer value that indicates the depth of relationships that should be traversed before reverting to a flat representation.
+## Specifying which fields should be read-only
+
+You may wish to specify multiple fields as read-only. Instead of adding each field explicitely with the `read_only=True` attribute, you may use the `read_only_fields` Meta option, like so:
+
+ class AccountSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Account
+ read_only_fields = ('created', 'modified')
+
## Customising the default fields
You can create customized subclasses of `ModelSerializer` that use a different set of default fields for the representation, by overriding various `get_<field_type>_field` methods.
diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md
index 4f87b30d..7884d096 100644
--- a/docs/api-guide/settings.md
+++ b/docs/api-guide/settings.md
@@ -96,11 +96,21 @@ Default: `rest_framework.serializers.ModelSerializer`
Default: `rest_framework.pagination.PaginationSerializer`
-## FORMAT_SUFFIX_KWARG
+## FILTER_BACKEND
-**TODO**
+The filter backend class that should be used for generic filtering. If set to `None` then generic filtering is disabled.
-Default: `'format'`
+## PAGINATE_BY
+
+The default page size to use for pagination. If set to `None`, pagination is disabled by default.
+
+Default: `None`
+
+## PAGINATE_BY_KWARG
+
+The name of a query parameter, which can be used by the client to overide the default page size to use for pagination. If set to `None`, clients may not override the default page size.
+
+Default: `None`
## UNAUTHENTICATED_USER
@@ -150,4 +160,10 @@ Default: `'accept'`
Default: `'format'`
+## FORMAT_SUFFIX_KWARG
+
+**TODO**
+
+Default: `'format'`
+
[cite]: http://www.python.org/dev/peps/pep-0020/
diff --git a/docs/api-guide/views.md b/docs/api-guide/views.md
index 5b072827..d1e42ec1 100644
--- a/docs/api-guide/views.md
+++ b/docs/api-guide/views.md
@@ -19,6 +19,10 @@ Using the `APIView` class is pretty much the same as using a regular `View` clas
For example:
+ from rest_framework.views import APIView
+ from rest_framework.response import Response
+ from rest_framework import authentication, permissions
+
class ListUsers(APIView):
"""
View to list all users in the system.