diff options
Diffstat (limited to 'docs/api-guide')
| -rw-r--r-- | docs/api-guide/authentication.md | 131 | ||||
| -rw-r--r-- | docs/api-guide/fields.md | 39 | ||||
| -rw-r--r-- | docs/api-guide/filtering.md | 8 | ||||
| -rw-r--r-- | docs/api-guide/permissions.md | 7 | ||||
| -rw-r--r-- | docs/api-guide/serializers.md | 2 | ||||
| -rw-r--r-- | docs/api-guide/settings.md | 106 |
6 files changed, 262 insertions, 31 deletions
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index fae86386..541c6575 100644 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -111,9 +111,14 @@ Unauthenticated responses that are denied permission will result in an `HTTP 401 ## TokenAuthentication -This authentication scheme uses a simple token-based HTTP Authentication scheme. Token authentication is appropriate for client-server setups, such as native desktop and mobile clients. +This authentication scheme uses a simple token-based HTTP Authentication scheme. Token authentication is appropriate for client-server setups, such as native desktop and mobile clients. -To use the `TokenAuthentication` scheme, include `rest_framework.authtoken` in your `INSTALLED_APPS` setting. +To use the `TokenAuthentication` scheme, include `rest_framework.authtoken` in your `INSTALLED_APPS` setting: + + INSTALLED_APPS = ( + ... + 'rest_framework.authtoken' + ) You'll also need to create tokens for your users. @@ -135,10 +140,14 @@ Unauthenticated responses that are denied permission will result in an `HTTP 401 WWW-Authenticate: Token +--- + **Note:** If you use `TokenAuthentication` in production you must ensure that your API is only available over `https` only. --- +#### Generating Tokens + 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) @@ -154,8 +163,7 @@ If you've already created some users, you can generate tokens for all existing u 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: +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') @@ -169,6 +177,23 @@ The `obtain_auth_token` view will return a JSON response when valid `username` a Note that the default `obtain_auth_token` view explicitly uses JSON requests and responses, rather than using default renderer and parser classes in your settings. If you need a customized version of the `obtain_auth_token` view, you can do so by overriding the `ObtainAuthToken` view class, and using that in your url conf instead. +#### Custom user models + +The `rest_framework.authtoken` app includes a south migration that will create the authtoken table. If you're using a [custom user model][custom-user-model] you'll need to make sure that any initial migration that creates the user table runs before the authtoken table is created. + +You can do so by inserting a `needed_by` attribute in your user migration: + + class Migration: + + needed_by = ( + ('authtoken', '0001_initial'), + ) + + def forwards(self): + ... + +For more details, see the [south documentation on dependencies][south-dependencies]. + ## SessionAuthentication This authentication scheme uses Django's default session backend for authentication. Session authentication is appropriate for AJAX clients that are running in the same session context as your website. @@ -182,6 +207,97 @@ Unauthenticated responses that are denied permission will result in an `HTTP 403 If you're using an AJAX style API with SessionAuthentication, you'll need to make sure you include a valid CSRF token for any "unsafe" HTTP method calls, such as `PUT`, `PATCH`, `POST` or `DELETE` requests. See the [Django CSRF documentation][csrf-ajax] for more details. +## OAuthAuthentication + +This authentication uses [OAuth 1.0a][oauth-1.0a] authentication scheme. OAuth 1.0a provides signature validation which provides a reasonable level of security over plain non-HTTPS connections. However, it may also be considered more complicated than OAuth2, as it requires clients to sign their requests. + +This authentication class depends on the optional `django-oauth-plus` and `oauth2` packages. In order to make it work you must install these packages and add `oauth_provider` to your `INSTALLED_APPS`: + + INSTALLED_APPS = ( + ... + `oauth_provider`, + ) + +Don't forget to run `syncdb` once you've added the package. + + python manage.py syncdb + +#### Getting started with django-oauth-plus + +The OAuthAuthentication class only provides token verification and signature validation for requests. It doesn't provide authorization flow for your clients. You still need to implement your own views for accessing and authorizing tokens. + +The `django-oauth-plus` package provides simple foundation for classic 'three-legged' oauth flow. Please refer to [the documentation][django-oauth-plus] for more details. + +## OAuth2Authentication + +This authentication uses [OAuth 2.0][rfc6749] authentication scheme. OAuth2 is more simple to work with than OAuth1, and provides much better security than simple token authentication. It is an unauthenticated scheme, and requires you to use an HTTPS connection. + +This authentication class depends on the optional [django-oauth2-provider][django-oauth2-provider] project. In order to make it work you must install this package and add `provider` and `provider.oauth2` to your `INSTALLED_APPS`: + + INSTALLED_APPS = ( + ... + 'provider', + 'provider.oauth2', + ) + +You must also include the following in your root `urls.py` module: + + url(r'^oauth2/', include('provider.oauth2.urls', namespace='oauth2')), + +Note that the `namespace='oauth2'` argument is required. + +Finally, sync your database. + + python manage.py syncdb + python manage.py migrate + +--- + +**Note:** If you use `OAuth2Authentication` in production you must ensure that your API is only available over `https` only. + +--- + +#### Getting started with django-oauth2-provider + +The `OAuth2Authentication` class only provides token verification for requests. It doesn't provide authorization flow for your clients. + +The OAuth 2 authorization flow is taken care by the [django-oauth2-provider][django-oauth2-provider] dependency. A walkthrough is given here, but for more details you should refer to [the documentation][django-oauth2-provider-docs]. + +To get started: + +##### 1. Create a client + +You can create a client, either through the shell, or by using the Django admin. + +Go to the admin panel and create a new `Provider.Client` entry. It will create the `client_id` and `client_secret` properties for you. + +##### 2. Request an access token + +To request an access token, submit a `POST` request to the url `/oauth2/access_token` with the following fields: + +* `client_id` the client id you've just configured at the previous step. +* `client_secret` again configured at the previous step. +* `username` the username with which you want to log in. +* `password` well, that speaks for itself. + +You can use the command line to test that your local configuration is working: + + curl -X POST -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=password&username=YOUR_USERNAME&password=YOUR_PASSWORD" http://localhost:8000/oauth2/access_token/ + +You should get a response that looks something like this: + + {"access_token": "<your-access-token>", "scope": "read", "expires_in": 86399, "refresh_token": "<your-refresh-token>"} + +##### 3. Access the API + +The only thing needed to make the `OAuth2Authentication` class work is to insert the `access_token` you've received in the `Authorization` request header. + +The command line to test the authentication looks like: + + curl -H "Authorization: Bearer <your-access-token>" http://localhost:8000/api/?client_id=YOUR_CLIENT_ID\&client_secret=YOUR_CLIENT_SECRET + +--- + # Custom authentication To implement a custom authentication scheme, subclass `BaseAuthentication` and override the `.authenticate(self, request)` method. The method should return a two-tuple of `(user, auth)` if authentication succeeds, or `None` otherwise. @@ -233,5 +349,12 @@ HTTP digest authentication is a widely implemented scheme that was intended to r [throttling]: throttling.md [csrf-ajax]: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax [mod_wsgi_official]: http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIPassAuthorization +[custom-user-model]: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model +[south-dependencies]: http://south.readthedocs.org/en/latest/dependencies.html [juanriaza]: https://github.com/juanriaza [djangorestframework-digestauth]: https://github.com/juanriaza/django-rest-framework-digestauth +[oauth-1.0a]: http://oauth.net/core/1.0a +[django-oauth-plus]: http://code.larlet.fr/django-oauth-plus +[django-oauth2-provider]: https://github.com/caffeinehit/django-oauth2-provider +[django-oauth2-provider-docs]: https://django-oauth2-provider.readthedocs.org/en/latest/ +[rfc6749]: http://tools.ietf.org/html/rfc6749 diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index d7f9197f..9a745cf1 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -2,7 +2,7 @@ # Serializer fields -> Each field in a Form class is responsible not only for validating data, but also for "cleaning" it -- normalizing it to a consistent format. +> Each field in a Form class is responsible not only for validating data, but also for "cleaning" it — normalizing it to a consistent format. > > — [Django documentation][cite] @@ -181,12 +181,6 @@ Corresponds to `django.forms.fields.RegexField` **Signature:** `RegexField(regex, max_length=None, min_length=None)` -## DateField - -A date representation. - -Corresponds to `django.db.models.fields.DateField` - ## DateTimeField A date and time representation. @@ -203,12 +197,41 @@ If you want to override this behavior, you'll need to declare the `DateTimeField class Meta: model = Comment +**Signature:** `DateTimeField(format=None, input_formats=None)` + +* `format` - A string representing the output format. If not specified, the `DATETIME_FORMAT` setting will be used, which defaults to `'iso-8601'`. +* `input_formats` - A list of strings representing the input formats which may be used to parse the date. If not specified, the `DATETIME_INPUT_FORMATS` setting will be used, which defaults to `['iso-8601']`. + +DateTime format strings may either be [python strftime formats][strftime] which explicitly specifiy the format, or the special string `'iso-8601'`, which indicates that [ISO 8601][iso8601] style datetimes should be used. (eg `'2013-01-29T12:34:56.000000'`) + +## DateField + +A date representation. + +Corresponds to `django.db.models.fields.DateField` + +**Signature:** `DateField(format=None, input_formats=None)` + +* `format` - A string representing the output format. If not specified, the `DATE_FORMAT` setting will be used, which defaults to `'iso-8601'`. +* `input_formats` - A list of strings representing the input formats which may be used to parse the date. If not specified, the `DATE_INPUT_FORMATS` setting will be used, which defaults to `['iso-8601']`. + +Date format strings may either be [python strftime formats][strftime] which explicitly specifiy the format, or the special string `'iso-8601'`, which indicates that [ISO 8601][iso8601] style dates should be used. (eg `'2013-01-29'`) + ## TimeField A time representation. +Optionally takes `format` as parameter to replace the matching pattern. + Corresponds to `django.db.models.fields.TimeField` +**Signature:** `TimeField(format=None, input_formats=None)` + +* `format` - A string representing the output format. If not specified, the `TIME_FORMAT` setting will be used, which defaults to `'iso-8601'`. +* `input_formats` - A list of strings representing the input formats which may be used to parse the date. If not specified, the `TIME_INPUT_FORMATS` setting will be used, which defaults to `['iso-8601']`. + +Time format strings may either be [python strftime formats][strftime] which explicitly specifiy the format, or the special string `'iso-8601'`, which indicates that [ISO 8601][iso8601] style times should be used. (eg `'12:34:56.000000'`) + ## IntegerField An integer representation. @@ -252,3 +275,5 @@ Django's regular [FILE_UPLOAD_HANDLERS] are used for handling uploaded files. [cite]: https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.cleaned_data [FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS +[strftime]: http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior +[iso8601]: http://www.w3.org/TR/NOTE-datetime diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index 53ea7cbc..ed946368 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -140,6 +140,14 @@ For more details on using filter sets see the [django-filter documentation][djan --- +### Filtering and object lookups + +Note that if a filter backend is configured for a view, then as well as being used to filter list views, it will also be used to filter the querysets used for returning a single object. + +For instance, given the previous example, and a product with an id of `4675`, the following URL would either return the corresponding object, or return a 404 response, depending on if the filtering conditions were met by the given product instance: + + 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: diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index 2db6ce1e..719ac1ef 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -90,12 +90,17 @@ This permission is suitable if you want to your API to allow read permissions to ## DjangoModelPermissions -This permission class ties into Django's standard `django.contrib.auth` [model permissions][contribauth]. When applied to a view that has a `.model` property, authorization will only be granted if the user has the relevant model permissions assigned. +This permission class ties into Django's standard `django.contrib.auth` [model permissions][contribauth]. When applied to a view that has a `.model` property, authorization will only be granted if the user *is authenticated* and has the *relevant model permissions* assigned. * `POST` requests require the user to have the `add` permission on the model. * `PUT` and `PATCH` requests require the user to have the `change` permission on the model. * `DELETE` requests require the user to have the `delete` permission on the model. +If you want to use `DjangoModelPermissions` but also allow unauthenticated users to have read permission, override the class and set the `authenticated_users_only` property to `False`. For example: + + class HasModelPermissionsOrReadOnly(DjangoModelPermissions): + authenticated_users_only = False + The default behaviour can also be overridden to support custom model permissions. For example, you might want to include a `view` model permission for `GET` requests. To use custom model permissions, override `DjangoModelPermissions` and set the `.perms_map` property. Refer to the source code for details. diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index 6f1f2883..de2cf7d8 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -93,6 +93,8 @@ To serialize a queryset instead of an object instance, you should pass the `many 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. +When deserialising a list of items, errors will be returned as a list of tuples. The first item in an error tuple will be the index of the item with the error in the original data; The second item in the tuple will be a dict with the individual errors for that item. + ### Field-level validation You can specify custom field-level validation by adding `.validate_<fieldname>` methods to your `Serializer` subclass. These are analagous to `.clean_<fieldname>` methods on Django forms, but accept slightly different arguments. diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index e103fbab..11638696 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -34,7 +34,11 @@ The `api_settings` object will check for any user-defined settings, and otherwis # API Reference -## DEFAULT_RENDERER_CLASSES +## API policy settings + +*The following settings control the basic API policies, and are applied to every `APIView` class based view, or `@api_view` function based view.* + +#### DEFAULT_RENDERER_CLASSES A list or tuple of renderer classes, that determines the default set of renderers that may be used when returning a `Response` object. @@ -45,7 +49,7 @@ Default: 'rest_framework.renderers.BrowsableAPIRenderer', ) -## DEFAULT_PARSER_CLASSES +#### DEFAULT_PARSER_CLASSES A list or tuple of parser classes, that determines the default set of parsers used when accessing the `request.DATA` property. @@ -57,7 +61,7 @@ Default: 'rest_framework.parsers.MultiPartParser' ) -## DEFAULT_AUTHENTICATION_CLASSES +#### DEFAULT_AUTHENTICATION_CLASSES A list or tuple of authentication classes, that determines the default set of authenticators used when accessing the `request.user` or `request.auth` properties. @@ -68,7 +72,7 @@ Default: 'rest_framework.authentication.BasicAuthentication' ) -## DEFAULT_PERMISSION_CLASSES +#### DEFAULT_PERMISSION_CLASSES A list or tuple of permission classes, that determines the default set of permissions checked at the start of a view. @@ -78,59 +82,77 @@ Default: 'rest_framework.permissions.AllowAny', ) -## DEFAULT_THROTTLE_CLASSES +#### DEFAULT_THROTTLE_CLASSES A list or tuple of throttle classes, that determines the default set of throttles checked at the start of a view. Default: `()` -## DEFAULT_CONTENT_NEGOTIATION_CLASS +#### DEFAULT_CONTENT_NEGOTIATION_CLASS A content negotiation class, that determines how a renderer is selected for the response, given an incoming request. Default: `'rest_framework.negotiation.DefaultContentNegotiation'` -## DEFAULT_MODEL_SERIALIZER_CLASS +--- + +## Generic view settings + +*The following settings control the behavior of the generic class based views.* + +#### DEFAULT_MODEL_SERIALIZER_CLASS A class that determines the default type of model serializer that should be used by a generic view if `model` is specified, but `serializer_class` is not provided. Default: `'rest_framework.serializers.ModelSerializer'` -## DEFAULT_PAGINATION_SERIALIZER_CLASS +#### DEFAULT_PAGINATION_SERIALIZER_CLASS A class the determines the default serialization style for paginated responses. Default: `rest_framework.pagination.PaginationSerializer` -## FILTER_BACKEND +#### FILTER_BACKEND The filter backend class that should be used for generic filtering. If set to `None` then generic filtering is disabled. -## PAGINATE_BY +#### PAGINATE_BY The default page size to use for pagination. If set to `None`, pagination is disabled by default. Default: `None` -## PAGINATE_BY_PARAM +#### 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 set to `None`, clients may not override the default page size. Default: `None` -## UNAUTHENTICATED_USER +--- + +## Authentication settings + +*The following settings control the behavior of unauthenticated requests.* + +#### UNAUTHENTICATED_USER The class that should be used to initialize `request.user` for unauthenticated requests. Default: `django.contrib.auth.models.AnonymousUser` -## UNAUTHENTICATED_TOKEN +#### UNAUTHENTICATED_TOKEN The class that should be used to initialize `request.auth` for unauthenticated requests. Default: `None` -## FORM_METHOD_OVERRIDE +--- + +## Browser overrides + +*The following settings provide URL or form-based overrides of the default browser behavior.* + +#### FORM_METHOD_OVERRIDE The name of a form field that may be used to override the HTTP method of the form. @@ -138,7 +160,7 @@ If the value of this setting is `None` then form method overloading will be disa Default: `'_method'` -## FORM_CONTENT_OVERRIDE +#### FORM_CONTENT_OVERRIDE The name of a form field that may be used to override the content of the form payload. Must be used together with `FORM_CONTENTTYPE_OVERRIDE`. @@ -146,7 +168,7 @@ If either setting is `None` then form content overloading will be disabled. Default: `'_content'` -## FORM_CONTENTTYPE_OVERRIDE +#### FORM_CONTENTTYPE_OVERRIDE The name of a form field that may be used to override the content type of the form payload. Must be used together with `FORM_CONTENT_OVERRIDE`. @@ -154,7 +176,7 @@ If either setting is `None` then form content overloading will be disabled. Default: `'_content_type'` -## URL_ACCEPT_OVERRIDE +#### URL_ACCEPT_OVERRIDE The name of a URL parameter that may be used to override the HTTP `Accept` header. @@ -162,13 +184,59 @@ If the value of this setting is `None` then URL accept overloading will be disab Default: `'accept'` -## URL_FORMAT_OVERRIDE +#### URL_FORMAT_OVERRIDE The name of a URL parameter that may be used to override the default `Accept` header based content negotiation. Default: `'format'` -## FORMAT_SUFFIX_KWARG +--- + +## Date/Time formatting + +*The following settings are used to control how date and time representations may be parsed and rendered.* + +#### DATETIME_FORMAT + +A format string that should be used by default for rendering the output of `DateTimeField` serializer fields. + +Default: `'iso-8601'` + +#### DATETIME_INPUT_FORMATS + +A list of format strings that should be used by default for parsing inputs to `DateTimeField` serializer fields. + +Default: `['iso-8601']` + +#### DATE_FORMAT + +A format string that should be used by default for rendering the output of `DateField` serializer fields. + +Default: `'iso-8601'` + +#### DATE_INPUT_FORMATS + +A list of format strings that should be used by default for parsing inputs to `DateField` serializer fields. + +Default: `['iso-8601']` + +#### TIME_FORMAT + +A format string that should be used by default for rendering the output of `TimeField` serializer fields. + +Default: `'iso-8601'` + +#### TIME_INPUT_FORMATS + +A list of format strings that should be used by default for parsing inputs to `TimeField` serializer fields. + +Default: `['iso-8601']` + +--- + +## Miscellaneous settings + +#### FORMAT_SUFFIX_KWARG The name of a parameter in the URL conf that may be used to provide a format suffix. |
