diff --git a/.travis.yml b/.travis.yml index 100a7cd8b..cd87dd339 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,44 +1,51 @@ language: python python: + - "2.7" + - "3.4" - "3.5" sudo: false env: - - TOX_ENV=py27-lint - - TOX_ENV=py27-docs - - TOX_ENV=py35-django19 - - TOX_ENV=py34-django19 - - TOX_ENV=py27-django19 - - TOX_ENV=py35-django18 - - TOX_ENV=py34-django18 - - TOX_ENV=py33-django18 - - TOX_ENV=py27-django18 - - TOX_ENV=py27-django110 - - TOX_ENV=py35-django110 - - TOX_ENV=py34-django110 - - TOX_ENV=py27-djangomaster - - TOX_ENV=py34-djangomaster - - TOX_ENV=py35-djangomaster + - DJANGO=1.8 + - DJANGO=1.9 + - DJANGO=1.10 + - DJANGO=1.11 + - DJANGO=master matrix: fast_finish: true + include: + - python: "3.6" + env: DJANGO=master + - python: "3.6" + env: DJANGO=1.11 + - python: "3.3" + env: DJANGO=1.8 + - python: "2.7" + env: TOXENV="lint" + - python: "2.7" + env: TOXENV="docs" + exclude: + - python: "2.7" + env: DJANGO=master + - python: "3.4" + env: DJANGO=master + allow_failures: - - env: TOX_ENV=py27-djangomaster - - env: TOX_ENV=py34-djangomaster - - env: TOX_ENV=py35-djangomaster + - env: DJANGO=master + - env: DJANGO=1.11 install: - # Virtualenv < 14 is required to keep the Python 3.2 builds running. - - pip install tox "virtualenv<14" + - pip install tox tox-travis script: - - tox -e $TOX_ENV + - tox after_success: - pip install codecov - - codecov -e TOX_ENV + - codecov -e TOXENV,DJANGO notifications: email: false diff --git a/LICENSE.md b/LICENSE.md index aca195ec4..4c599a394 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # License -Copyright (c) 2011-2016, Tom Christie +Copyright (c) 2011-2017, Tom Christie All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index 155f8dead..7d11aa081 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,13 @@ The initial aim is to provide a single full-time position on REST framework.

- - + + + +

-*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), and [Machinalis](http://www.machinalis.com/#services).* +*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), [Machinalis](https://hello.machinalis.co.uk/), [Rollbar](https://rollbar.com), and [MicroPyramid](https://micropyramid.com/django-rest-framework-development-services/).* --- diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..d7436ab05 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,7 @@ +coverage: + status: + project: false + patch: false + changes: false + +comment: off diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index bf3a31eb7..4a01188f3 100644 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -363,7 +363,7 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a [oauth]: http://oauth.net/2/ [permission]: permissions.md [throttling]: throttling.md -[csrf-ajax]: https://docs.djangoproject.com/en/dev/ref/csrf/#ajax +[csrf-ajax]: https://docs.djangoproject.com/en/stable/ref/csrf/#ajax [mod_wsgi_official]: http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIPassAuthorization [django-oauth-toolkit-getting-started]: https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html [django-rest-framework-oauth]: http://jpadilla.github.io/django-rest-framework-oauth/ diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 17168b721..677598205 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -261,7 +261,7 @@ Corresponds to `django.db.models.fields.DecimalField`. **Signature**: `DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)` -- `max_digits` The maximum number of digits allowed in the number. Note that this number must be greater than or equal to decimal_places. +- `max_digits` The maximum number of digits allowed in the number. It must be either `None` or an integer greater than or equal to `decimal_places`. - `decimal_places` The number of decimal places to store with the number. - `coerce_to_string` Set to `True` if string values should be returned for the representation, or `False` if `Decimal` objects should be returned. Defaults to the same value as the `COERCE_DECIMAL_TO_STRING` settings key, which will be `True` unless overridden. If `Decimal` objects are returned by the serializer, then the final output format will be determined by the renderer. Note that setting `localize` will force the value to `True`. - `max_value` Validate that the number provided is no greater than this value. @@ -303,8 +303,6 @@ Format strings may either be [Python strftime formats][strftime] which explicitl When a value of `None` is used for the format `datetime` objects will be returned by `to_representation` and the final output representation will determined by the renderer class. -In the case of JSON this means the default datetime representation uses the [ECMA 262 date time string specification][ecma262]. This is a subset of ISO 8601 which uses millisecond precision, and includes the 'Z' suffix for the UTC timezone, for example: `2013-01-29T12:34:56.123Z`. - #### `auto_now` and `auto_now_add` model fields. When using `ModelSerializer` or `HyperlinkedModelSerializer`, note that any model fields with `auto_now=True` or `auto_now_add=True` will use serializer fields that are `read_only=True` by default. @@ -434,9 +432,11 @@ Requires either the `Pillow` package or `PIL` package. The `Pillow` package is A field class that validates a list of objects. -**Signature**: `ListField(child)` +**Signature**: `ListField(child, min_length=None, max_length=None)` - `child` - A field instance that should be used for validating the objects in the list. If this argument is not provided then objects in the list will not be validated. +- `min_length` - Validates that the list contains no fewer than this number of elements. +- `max_length` - Validates that the list contains no more than this number of elements. For example, to validate a list of integers you might use something like the following: @@ -665,12 +665,12 @@ The [django-rest-framework-gis][django-rest-framework-gis] package provides geog The [django-rest-framework-hstore][django-rest-framework-hstore] package provides an `HStoreField` to support [django-hstore][django-hstore] `DictionaryField` model field. -[cite]: https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.cleaned_data +[cite]: https://docs.djangoproject.com/en/stable/ref/forms/api/#django.forms.Form.cleaned_data [html-and-forms]: ../topics/html-and-forms.md -[FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS +[FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS [ecma262]: http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 -[strftime]: http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior -[django-widgets]: https://docs.djangoproject.com/en/dev/ref/forms/widgets/ +[strftime]: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior +[django-widgets]: https://docs.djangoproject.com/en/stable/ref/forms/widgets/ [iso8601]: http://www.w3.org/TR/NOTE-datetime [drf-compound-fields]: https://drf-compound-fields.readthedocs.io [drf-extra-fields]: https://github.com/Hipo/drf-extra-fields diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index 3f212ced3..8a23a2ea3 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -455,14 +455,14 @@ The [djangorestframework-word-filter][django-rest-framework-word-search-filter] [drf-url-filter][drf-url-filter] is a simple Django app to apply filters on drf `ModelViewSet`'s `Queryset` in a clean, simple and configurable way. It also supports validations on incoming query params and their values. A beautiful python package `Voluptuous` is being used for validations on the incoming query parameters. The best part about voluptuous is you can define your own validations as per your query params requirements. -[cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters +[cite]: https://docs.djangoproject.com/en/stable/topics/db/queries/#retrieving-specific-objects-with-filters [django-filter]: https://github.com/alex/django-filter [django-filter-docs]: https://django-filter.readthedocs.io/en/latest/index.html [guardian]: https://django-guardian.readthedocs.io/ [view-permissions]: https://django-guardian.readthedocs.io/en/latest/userguide/assign.html [view-permissions-blogpost]: http://blog.nyaruka.com/adding-a-view-permission-to-django-models [nullbooleanselect]: https://github.com/django/django/blob/master/django/forms/widgets.py -[search-django-admin]: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields +[search-django-admin]: https://docs.djangoproject.com/en/stable/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields [django-rest-framework-filters]: https://github.com/philipn/django-rest-framework-filters [django-rest-framework-word-search-filter]: https://github.com/trollknurr/django-rest-framework-word-search-filter [django-url-filter]: https://github.com/miki725/django-url-filter diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index c368d0b46..ae2705080 100644 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -69,7 +69,7 @@ The following attributes control the basic view behavior. The following attributes are used to control pagination when used with list views. -* `pagination_class` - The pagination class that should be used when paginating list results. Defaults to the same value as the `DEFAULT_PAGINATION_CLASS` setting, which is `'rest_framework.pagination.PageNumberPagination'`. +* `pagination_class` - The pagination class that should be used when paginating list results. Defaults to the same value as the `DEFAULT_PAGINATION_CLASS` setting, which is `'rest_framework.pagination.PageNumberPagination'`. Setting `pagination_class=None` will disable pagination on this view. **Filtering**: @@ -382,7 +382,7 @@ The [django-rest-framework-bulk package][django-rest-framework-bulk] implements [Django Rest Multiple Models][django-rest-multiple-models] provides a generic view (and mixin) for sending multiple serialized models and/or querysets via a single API request. -[cite]: https://docs.djangoproject.com/en/dev/ref/class-based-views/#base-vs-generic-views +[cite]: https://docs.djangoproject.com/en/stable/ref/class-based-views/#base-vs-generic-views [GenericAPIView]: #genericapiview [ListModelMixin]: #listmodelmixin [CreateModelMixin]: #createmodelmixin diff --git a/docs/api-guide/metadata.md b/docs/api-guide/metadata.md index e12aeb7fd..de28ffd8a 100644 --- a/docs/api-guide/metadata.md +++ b/docs/api-guide/metadata.md @@ -104,6 +104,18 @@ Then configure your settings to use this custom class: 'DEFAULT_METADATA_CLASS': 'myproject.apps.core.MinimalMetadata' } +# Third party packages + +The following third party packages provide additional metadata implementations. + +## DRF-schema-adapter + +[drf-schema-adapter][drf-schema-adapter] is a set of tools that makes it easier to provide schema information to frontend frameworks and libraries. It provides a metadata mixin as well as 2 metadata classes and several adapters suitable to generate [json-schema][json-schema] as well as schema information readable by various libraries. + +You can also write your own adapter to work with your specific frontend. +If you wish to do so, it also provides an exporter that can export those schema information to json files. + [cite]: http://tools.ietf.org/html/rfc7231#section-4.3.7 [no-options]: https://www.mnot.net/blog/2012/10/29/NO_OPTIONS [json-schema]: http://json-schema.org/ +[drf-schema-adapter]: https://github.com/drf-forms/drf-schema-adapter diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md index f82614eca..bc7a5602d 100644 --- a/docs/api-guide/pagination.md +++ b/docs/api-guide/pagination.md @@ -325,7 +325,7 @@ The [`DRF-extensions` package][drf-extensions] includes a [`PaginateByMaxMixin` The [`drf-proxy-pagination` package][drf-proxy-pagination] includes a `ProxyPagination` class which allows to choose pagination class with a query parameter. -[cite]: https://docs.djangoproject.com/en/dev/topics/pagination/ +[cite]: https://docs.djangoproject.com/en/stable/topics/pagination/ [github-link-pagination]: https://developer.github.com/guides/traversing-with-pagination/ [link-header]: ../img/link-header-pagination.png [drf-extensions]: http://chibisov.github.io/drf-extensions/docs/ diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md index ef2859fe1..7bf932d06 100644 --- a/docs/api-guide/parsers.md +++ b/docs/api-guide/parsers.md @@ -224,7 +224,7 @@ Modify your REST framework settings. [jquery-ajax]: http://api.jquery.com/jQuery.ajax/ [cite]: https://groups.google.com/d/topic/django-developers/dxI4qVzrBY4/discussion -[upload-handlers]: https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#upload-handlers +[upload-handlers]: https://docs.djangoproject.com/en/stable/topics/http/file-uploads/#upload-handlers [rest-framework-yaml]: http://jpadilla.github.io/django-rest-framework-yaml/ [rest-framework-xml]: http://jpadilla.github.io/django-rest-framework-xml/ [yaml]: http://www.yaml.org/ diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index 7cdb59531..548b14438 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -164,7 +164,7 @@ As with `DjangoModelPermissions`, this permission must only be applied to views Note that `DjangoObjectPermissions` **does not** require the `django-guardian` package, and should support other object-level backends equally well. -As with `DjangoModelPermissions` you can use custom model permissions by overriding `DjangoModelPermissions` and setting the `.perms_map` property. Refer to the source code for details. +As with `DjangoModelPermissions` you can use custom model permissions by overriding `DjangoObjectPermissions` and setting the `.perms_map` property. Refer to the source code for details. --- @@ -259,18 +259,22 @@ The [REST Condition][rest-condition] package is another extension for building c ## DRY Rest Permissions -The [DRY Rest Permissions][dry-rest-permissions] package provides the ability to define different permissions for individual default and custom actions. This package is made for apps with permissions that are derived from relationships defined in the app's data model. It also supports permission checks being returned to a client app through the API's serializer. Additionally it supports adding permissions to the default and custom list actions to restrict the data they retrive per user. +The [DRY Rest Permissions][dry-rest-permissions] package provides the ability to define different permissions for individual default and custom actions. This package is made for apps with permissions that are derived from relationships defined in the app's data model. It also supports permission checks being returned to a client app through the API's serializer. Additionally it supports adding permissions to the default and custom list actions to restrict the data they retrieve per user. ## Django Rest Framework Roles The [Django Rest Framework Roles][django-rest-framework-roles] package makes it easier to parameterize your API over multiple types of users. +## Django Rest Framework API Key + +The [Django Rest Framework API Key][django-rest-framework-api-key] package allows you to ensure that every request made to the server requires an API key header. You can generate one from the django admin interface. + [cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html [authentication]: authentication.md [throttling]: throttling.md [filtering]: filtering.md -[contribauth]: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#custom-permissions -[objectpermissions]: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#handling-object-permissions +[contribauth]: https://docs.djangoproject.com/en/stable/topics/auth/customizing/#custom-permissions +[objectpermissions]: https://docs.djangoproject.com/en/stable/topics/auth/customizing/#handling-object-permissions [guardian]: https://github.com/lukaszb/django-guardian [get_objects_for_user]: http://pythonhosted.org/django-guardian/api/guardian.shortcuts.html#get-objects-for-user [2.2-announcement]: ../topics/2.2-announcement.md @@ -280,3 +284,4 @@ The [Django Rest Framework Roles][django-rest-framework-roles] package makes it [rest-condition]: https://github.com/caxap/rest_condition [dry-rest-permissions]: https://github.com/Helioscene/dry-rest-permissions [django-rest-framework-roles]: https://github.com/computer-lab/django-rest-framework-roles +[django-rest-framework-api-key]: https://github.com/manosim/django-rest-framework-api-key diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md index aabe49412..662fd4809 100644 --- a/docs/api-guide/relations.md +++ b/docs/api-guide/relations.md @@ -505,7 +505,7 @@ For example, given the following model for a tag, which has a generic relationsh """ Tags arbitrary model instances using a generic relation. - See: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/ + See: https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/ """ tag_name = models.SlugField() content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) @@ -593,9 +593,9 @@ The [drf-nested-routers package][drf-nested-routers] provides routers and relati The [rest-framework-generic-relations][drf-nested-relations] library provides read/write serialization for generic foreign keys. [cite]: http://lwn.net/Articles/193245/ -[reverse-relationships]: https://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward +[reverse-relationships]: https://docs.djangoproject.com/en/stable/topics/db/queries/#following-relationships-backward [routers]: http://www.django-rest-framework.org/api-guide/routers#defaultrouter -[generic-relations]: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1 +[generic-relations]: https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/#id1 [2.2-announcement]: ../topics/2.2-announcement.md [drf-nested-routers]: https://github.com/alanjds/drf-nested-routers [drf-nested-relations]: https://github.com/Ian-Foote/rest-framework-generic-relations diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index a95778350..236504850 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -123,6 +123,8 @@ You can use `TemplateHTMLRenderer` either to return regular HTML pages using RES 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. +See the [_HTML & Forms_ Topic Page][html-and-forms] for further examples of `TemplateHTMLRenderer` usage. + **.media_type**: `text/html` **.format**: `'.html'` @@ -476,7 +478,7 @@ Comma-separated values are a plain-text tabular data format, that can be easily [Rest Framework Latex] provides a renderer that outputs PDFs using Laulatex. It is maintained by [Pebble (S/F Software)][mypebble]. -[cite]: https://docs.djangoproject.com/en/dev/ref/template-response/#the-rendering-process +[cite]: https://docs.djangoproject.com/en/stable/stable/template-response/#the-rendering-process [conneg]: content-negotiation.md [html-and-forms]: ../topics/html-and-forms.md [browser-accept-headers]: http://www.gethifi.com/blog/browser-rest-http-accept-headers @@ -485,7 +487,7 @@ Comma-separated values are a plain-text tabular data format, that can be easily [quote]: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven [application/vnd.github+json]: http://developer.github.com/v3/media/ [application/vnd.collection+json]: http://www.amundsen.com/media-types/collection/ -[django-error-views]: https://docs.djangoproject.com/en/dev/topics/http/views/#customizing-error-views +[django-error-views]: https://docs.djangoproject.com/en/stable/topics/http/views/#customizing-error-views [rest-framework-jsonp]: http://jpadilla.github.io/django-rest-framework-jsonp/ [cors]: http://www.w3.org/TR/cors/ [cors-docs]: http://www.django-rest-framework.org/topics/ajax-csrf-cors/ diff --git a/docs/api-guide/responses.md b/docs/api-guide/responses.md index 97f312710..8ee14eefa 100644 --- a/docs/api-guide/responses.md +++ b/docs/api-guide/responses.md @@ -91,5 +91,5 @@ As with any other `TemplateResponse`, this method is called to render the serial 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/ +[cite]: https://docs.djangoproject.com/en/stable/stable/template-response/ [statuscodes]: status-codes.md diff --git a/docs/api-guide/reverse.md b/docs/api-guide/reverse.md index 35d88e2db..ee0b2054f 100644 --- a/docs/api-guide/reverse.md +++ b/docs/api-guide/reverse.md @@ -51,5 +51,5 @@ As with the `reverse` function, you should **include the request as a keyword ar api_root = reverse_lazy('api-root', request=request) [cite]: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5 -[reverse]: https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse -[reverse-lazy]: https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-lazy +[reverse]: https://docs.djangoproject.com/en/stable/topics/http/urls/#reverse +[reverse-lazy]: https://docs.djangoproject.com/en/stable/topics/http/urls/#reverse-lazy diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 10a86bdf0..d3f4186ad 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -118,6 +118,26 @@ The above example would now generate the following URL pattern: * URL pattern: `^users/{pk}/change-password/$` Name: `'user-change-password'` +In the case you do not want to use the default name generated for your custom action, you can use the url_name parameter to customize it. + +For example, if you want to change the name of our custom action to `'user-change-password'`, you could write: + + from myapp.permissions import IsAdminOrIsSelf + from rest_framework.decorators import detail_route + + class UserViewSet(ModelViewSet): + ... + + @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf], url_name='change-password') + def set_password(self, request, pk=None): + ... + +The above example would now generate the following URL pattern: + +* URL pattern: `^users/{pk}/set_password/$` Name: `'user-change-password'` + +You can also use url_path and url_name parameters together to obtain extra control on URL generation for custom views. + For more information see the viewset documentation on [marking extra actions for routing][route-decorators]. # API Guide diff --git a/docs/api-guide/schemas.md b/docs/api-guide/schemas.md index 7da619034..f43ff56bd 100644 --- a/docs/api-guide/schemas.md +++ b/docs/api-guide/schemas.md @@ -145,6 +145,18 @@ May be used to pass a canonical URL for the schema. url='https://www.example.org/api/' ) +#### `urlconf` + +A string representing the import path to the URL conf that you want +to generate an API schema for. This defaults to the value of Django's +ROOT_URLCONF setting. + + schema_view = get_schema_view( + title='Server Monitoring API', + url='https://www.example.org/api/', + urlconf='myproject.urls' + ) + #### `renderer_classes` May be used to pass the set of renderer classes that can be used to render the API root endpoint. @@ -281,8 +293,8 @@ A generic view with sections in the class docstring, using single-line style. class UserList(generics.ListCreateAPIView): """ - get: Create a new user. - post: List all the users. + get: List all the users. + post: Create a new user. """ queryset = User.objects.all() serializer_class = UserSerializer @@ -541,5 +553,5 @@ A short description of the meaning and intended usage of the input field. [open-api]: https://openapis.org/ [json-hyperschema]: http://json-schema.org/latest/json-schema-hypermedia.html [api-blueprint]: https://apiblueprint.org/ -[static-files]: https://docs.djangoproject.com/en/dev/howto/static-files/ -[named-arguments]: https://docs.djangoproject.com/en/dev/topics/http/urls/#named-groups +[static-files]: https://docs.djangoproject.com/en/stable/howto/static-files/ +[named-arguments]: https://docs.djangoproject.com/en/stable/topics/http/urls/#named-groups diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index 290e32f4f..a3f7fdcc1 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -578,16 +578,6 @@ Alternative representations include serializing using hyperlinks, serializing co For full details see the [serializer relations][relations] documentation. -## Inheritance of the 'Meta' class - -The inner `Meta` class on serializers is not inherited from parent classes by default. This is the same behavior as with Django's `Model` and `ModelForm` classes. If you want the `Meta` class to inherit from a parent class you must do so explicitly. For example: - - class AccountSerializer(MyBaseSerializer): - class Meta(MyBaseSerializer.Meta): - model = Account - -Typically we would recommend *not* using inheritance on inner Meta classes, but instead declaring all options explicitly. - ## Customizing field mappings The ModelSerializer class also exposes an API that you can override in order to alter how serializer fields are automatically determined when instantiating the serializer. @@ -710,7 +700,7 @@ You can override a URL field view name and lookup field by using either, or both model = Account fields = ('account_url', 'account_name', 'users', 'created') extra_kwargs = { - 'url': {'view_name': 'accounts', 'lookup_field': 'account_name'} + 'url': {'view_name': 'accounts', 'lookup_field': 'account_name'}, 'users': {'lookup_field': 'username'} } @@ -1025,6 +1015,40 @@ If any of the validation fails, then the method should raise a `serializers.Vali The `data` argument passed to this method will normally be the value of `request.data`, so the datatype it provides will depend on the parser classes you have configured for your API. +## Serializer Inheritance + +Similar to Django forms, you can extend and reuse serializers through inheritance. This allows you to declare a common set of fields or methods on a parent class that can then be used in a number of serializers. For example, + + class MyBaseSerializer(Serializer): + my_field = serializers.CharField() + + def validate_my_field(self): + ... + + class MySerializer(MyBaseSerializer): + ... + +Like Django's `Model` and `ModelForm` classes, the inner `Meta` class on serializers does not implicitly inherit from it's parents' inner `Meta` classes. If you want the `Meta` class to inherit from a parent class you must do so explicitly. For example: + + class AccountSerializer(MyBaseSerializer): + class Meta(MyBaseSerializer.Meta): + model = Account + +Typically we would recommend *not* using inheritance on inner Meta classes, but instead declaring all options explicitly. + +Additionally, the following caveats apply to serializer inheritance: + +* Normal Python name resolution rules apply. If you have multiple base classes that declare a `Meta` inner class, only the first one will be used. This means the child’s `Meta`, if it exists, otherwise the `Meta` of the first parent, etc. +* It’s possible to declaratively remove a `Field` inherited from a parent class by setting the name to be `None` on the subclass. + + class MyBaseSerializer(ModelSerializer): + my_field = serializers.CharField() + + class MySerializer(MyBaseSerializer): + my_field = None + + However, you can only use this technique to opt out from a field defined declaratively by a parent class; it won’t prevent the `ModelSerializer` from generating a default field. To opt-out from default fields, see [Specifying which fields to include](#specifying-which-fields-to-include). + ## Dynamically modifying fields Once a serializer has been initialized, the dictionary of fields that are set on the serializer may be accessed using the `.fields` attribute. Accessing and modifying this attribute allows you to dynamically modify the serializer. @@ -1076,8 +1100,6 @@ This API included the `.get_field()`, `.get_pk_field()` and other methods. Because the serializers have been fundamentally redesigned with 3.0 this API no longer exists. You can still modify the fields that get created but you'll need to refer to the source code, and be aware that if the changes you make are against private bits of API then they may be subject to change. -A new interface for controlling this behavior is currently planned for REST framework 3.1. - --- # Third party packages @@ -1112,13 +1134,36 @@ The [dynamic-rest][dynamic-rest] package extends the ModelSerializer and ModelVi The [drf-dynamic-fields][drf-dynamic-fields] package provides a mixin to dynamically limit the fields per serializer to a subset specified by an URL parameter. +## DRF FlexFields + +The [drf-flex-fields][drf-flex-fields] package extends the ModelSerializer and ModelViewSet to provide commonly used functionality for dynamically setting fields and expanding primitive fields to nested models, both from URL parameters and your serializer class definitions. + +## Serializer Extensions + +The [django-rest-framework-serializer-extensions][drf-serializer-extensions] +package provides a collection of tools to DRY up your serializers, by allowing +fields to be defined on a per-view/request basis. Fields can be whitelisted, +blacklisted and child serializers can be optionally expanded. + ## HTML JSON Forms The [html-json-forms][html-json-forms] package provides an algorithm and serializer for processing `
` submissions per the (inactive) [HTML JSON Form specification][json-form-spec]. The serializer facilitates processing of arbitrarily nested JSON structures within HTML. For example, `` will be interpreted as `{"items": [{"id": "5"}]}`. +## DRF-Base64 + +[DRF-Base64][drf-base64] provides a set of field and model serializers that handles the upload of base64-encoded files. + +## QueryFields + +[djangorestframework-queryfields][djangorestframework-queryfields] allows API clients to specify which fields will be sent in the response via inclusion/exclusion query parameters. + +## DRF Writable Nested + +The [drf-writable-nested][drf-writable-nested] package provides writable nested model serializer which allows to create/update models with nested related data. + [cite]: https://groups.google.com/d/topic/django-users/sVFaOfQi4wY/discussion [relations]: relations.md -[model-managers]: https://docs.djangoproject.com/en/dev/topics/db/managers/ +[model-managers]: https://docs.djangoproject.com/en/stable/topics/db/managers/ [encapsulation-blogpost]: http://www.dabapps.com/blog/django-models-and-encapsulation/ [django-rest-marshmallow]: http://tomchristie.github.io/django-rest-marshmallow/ [marshmallow]: https://marshmallow.readthedocs.io/en/latest/ @@ -1129,5 +1174,10 @@ The [html-json-forms][html-json-forms] package provides an algorithm and seriali [django-hstore]: https://github.com/djangonauts/django-hstore [dynamic-rest]: https://github.com/AltSchool/dynamic-rest [html-json-forms]: https://github.com/wq/html-json-forms +[drf-flex-fields]: https://github.com/rsinger86/drf-flex-fields [json-form-spec]: https://www.w3.org/TR/html-json-forms/ [drf-dynamic-fields]: https://github.com/dbrgn/drf-dynamic-fields +[drf-base64]: https://bitbucket.org/levit_scs/drf_base64 +[drf-serializer-extensions]: https://github.com/evenicoulddoit/django-rest-framework-serializer-extensions +[djangorestframework-queryfields]: http://djangorestframework-queryfields.readthedocs.io/ +[drf-writable-nested]: http://github.com/Brogency/drf-writable-nested diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 58ceeeeb4..aaedd463e 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -241,7 +241,7 @@ Default: If set, this maps the `'pk'` identifier in the URL conf onto the actual field name when generating a schema path parameter. Typically this will be `'id'`. This gives a more suitable representation as "primary key" is an implementation -detail, wheras "identifier" is a more general concept. +detail, whereas "identifier" is a more general concept. Default: `True` @@ -456,7 +456,7 @@ An integer of 0 or more, that may be used to specify the number of application p Default: `None` -[cite]: http://www.python.org/dev/peps/pep-0020/ +[cite]: https://www.python.org/dev/peps/pep-0020/ [rfc4627]: http://www.ietf.org/rfc/rfc4627.txt [heroku-minified-json]: https://github.com/interagent/http-api-design#keep-json-minified-in-all-responses -[strftime]: http://docs.python.org/2/library/time.html#time.strftime +[strftime]: https://docs.python.org/3/library/time.html#time.strftime diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md index de79a1e2f..13c746017 100644 --- a/docs/api-guide/testing.md +++ b/docs/api-guide/testing.md @@ -205,7 +205,9 @@ Note that the requests client requires you to pass fully qualified URLs. ## `RequestsClient` and working with the database -The `RequestsClient` class is useful if +The `RequestsClient` class is useful if you want to write tests that solely interact with the service interface. This is a little stricter than using the standard Django test client, as it means that all interactions should be via the API. + +If you're using `RequestsClient` you'll want to ensure that test setup, and results assertions are performed as regular API calls, rather than interacting with the database models directly. For example, rather than checking that `Customer.objects.count() == 3` you would list the customers endpoint, and ensure that it contains three records. ## Headers & Authentication @@ -373,6 +375,6 @@ For example, to add support for using `format='html'` in test requests, you migh } [cite]: http://jacobian.org/writing/django-apps-with-buildout/#s-create-a-test-wrapper -[client]: https://docs.djangoproject.com/en/dev/topics/testing/tools/#the-test-client -[requestfactory]: https://docs.djangoproject.com/en/dev/topics/testing/advanced/#django.test.client.RequestFactory +[client]: https://docs.djangoproject.com/en/stable/topics/testing/tools/#the-test-client +[requestfactory]: https://docs.djangoproject.com/en/stable/topics/testing/advanced/#django.test.client.RequestFactory [configuration]: #configuration diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md index da4d5f725..58578a23e 100644 --- a/docs/api-guide/throttling.md +++ b/docs/api-guide/throttling.md @@ -193,5 +193,5 @@ The following is an example of a rate throttle, that will randomly throttle 1 in [cite]: https://dev.twitter.com/docs/error-codes-responses [permissions]: permissions.md [identifing-clients]: http://oxpedia.org/wiki/index.php?title=AppSuite:Grizzly#Multiple_Proxies_in_front_of_the_cluster -[cache-setting]: https://docs.djangoproject.com/en/dev/ref/settings/#caches -[cache-docs]: https://docs.djangoproject.com/en/dev/topics/cache/#setting-up-the-cache +[cache-setting]: https://docs.djangoproject.com/en/stable/ref/settings/#caches +[cache-docs]: https://docs.djangoproject.com/en/stable/topics/cache/#setting-up-the-cache diff --git a/docs/api-guide/validators.md b/docs/api-guide/validators.md index e041e9072..0e58c6fff 100644 --- a/docs/api-guide/validators.md +++ b/docs/api-guide/validators.md @@ -300,4 +300,4 @@ In some advanced cases you might want a validator to be passed the serializer fi # In `__call__` we can then use that information to modify the validation behavior. self.is_update = serializer_field.parent.instance is not None -[cite]: https://docs.djangoproject.com/en/dev/ref/validators/ +[cite]: https://docs.djangoproject.com/en/stable/ref/validators/ diff --git a/docs/api-guide/views.md b/docs/api-guide/views.md index 55f6664e0..c0c4f67e4 100644 --- a/docs/api-guide/views.md +++ b/docs/api-guide/views.md @@ -73,6 +73,8 @@ The following methods are used by REST framework to instantiate the various plug ### .get_content_negotiator(self) +### .get_exception_handler(self) + ## API policy implementation methods The following methods are called before dispatching to the handler method. diff --git a/docs/img/premium/machinalis-readme.png b/docs/img/premium/machinalis-readme.png index 4bdb020c2..cd98c23c7 100644 Binary files a/docs/img/premium/machinalis-readme.png and b/docs/img/premium/machinalis-readme.png differ diff --git a/docs/img/premium/micropyramid-readme.png b/docs/img/premium/micropyramid-readme.png new file mode 100644 index 000000000..9fa9500e1 Binary files /dev/null and b/docs/img/premium/micropyramid-readme.png differ diff --git a/docs/img/premium/rollbar-readme.png b/docs/img/premium/rollbar-readme.png new file mode 100644 index 000000000..669612f72 Binary files /dev/null and b/docs/img/premium/rollbar-readme.png differ diff --git a/docs/img/premium/rover-readme.png b/docs/img/premium/rover-readme.png index c9865f2a9..b8055d62e 100644 Binary files a/docs/img/premium/rover-readme.png and b/docs/img/premium/rover-readme.png differ diff --git a/docs/img/premium/sentry-readme.png b/docs/img/premium/sentry-readme.png index 1e869f3b1..5536ce52f 100644 Binary files a/docs/img/premium/sentry-readme.png and b/docs/img/premium/sentry-readme.png differ diff --git a/docs/img/premium/stream-readme.png b/docs/img/premium/stream-readme.png index 955c11429..fc3733c70 100644 Binary files a/docs/img/premium/stream-readme.png and b/docs/img/premium/stream-readme.png differ diff --git a/docs/index.md b/docs/index.md index 9b0913f00..87ef0e9e3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -73,12 +73,14 @@ The initial aim is to provide a single full-time position on REST framework.
-*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), and [Machinalis](http://www.machinalis.com/#services).* +*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), [Machinalis](https://hello.machinalis.co.uk/), [Rollbar](https://rollbar.com), and [MicroPyramid](https://micropyramid.com/django-rest-framework-development-services/).* --- @@ -93,7 +95,7 @@ The following packages are optional: * [coreapi][coreapi] (1.32.0+) - Schema generation support. * [Markdown][markdown] (2.1.0+) - Markdown support for the browsable API. -* [django-filter][django-filter] (0.9.2+) - Filtering support. +* [django-filter][django-filter] (1.0.1+) - Filtering support. * [django-crispy-forms][django-crispy-forms] - Improved HTML display for filtering. * [django-guardian][django-guardian] (1.1.1+) - Object level permissions support. @@ -236,7 +238,8 @@ General guides to using REST framework. * [Browser enhancements][browser-enhancements] * [The Browsable API][browsableapi] * [REST, Hypermedia & HATEOAS][rest-hypermedia-hateoas] -* [Third Party Resources][third-party-resources] +* [Third Party Packages][third-party-packages] +* [Tutorials and Resources][tutorials-and-resources] * [Contributing to REST framework][contributing] * [Project management][project-management] * [3.0 Announcement][3.0-announcement] @@ -249,6 +252,7 @@ General guides to using REST framework. * [Mozilla Grant][mozilla-grant] * [Funding][funding] * [Release Notes][release-notes] +* [Jobs][jobs] ## Development @@ -260,7 +264,7 @@ Framework. For support please see the [REST framework discussion group][group], try the `#restframework` channel on `irc.freenode.net`, search [the IRC archives][botbot], or raise a question on [Stack Overflow][stack-overflow], making sure to include the ['django-rest-framework'][django-rest-framework-tag] tag. -[Paid support is available][paid-support] from [DabApps][dabapps], and can include work on REST framework core, or support with building your REST framework API. Please [contact DabApps][contact-dabapps] if you'd like to discuss commercial support options. +For priority support please sign up for a [professional or premium sponsorship plan](https://fund.django-rest-framework.org/topics/funding/). For updates on REST framework development, you may also want to follow [the author][twitter] on Twitter. @@ -365,7 +369,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [rest-hypermedia-hateoas]: topics/rest-hypermedia-hateoas.md [contributing]: topics/contributing.md [project-management]: topics/project-management.md -[third-party-resources]: topics/third-party-resources.md +[third-party-packages]: topics/third-party-packages.md +[tutorials-and-resources]: topics/tutorials-and-resources.md [3.0-announcement]: topics/3.0-announcement.md [3.1-announcement]: topics/3.1-announcement.md [3.2-announcement]: topics/3.2-announcement.md @@ -376,6 +381,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [mozilla-grant]: topics/mozilla-grant.md [funding]: topics/funding.md [release-notes]: topics/release-notes.md +[jobs]: topics/jobs.md [tox]: http://testrun.org/tox/latest/ diff --git a/docs/topics/2.2-announcement.md b/docs/topics/2.2-announcement.md index e6220f427..ca4ed2efa 100644 --- a/docs/topics/2.2-announcement.md +++ b/docs/topics/2.2-announcement.md @@ -147,10 +147,10 @@ When using a serializer with a `HyperlinkedRelatedField` or `HyperlinkedIdentity From version 2.2 onwards, serializers with hyperlinked relationships *always* require a `'request'` key to be supplied in the context dictionary. The implicit behavior will continue to function, but its use will raise a `PendingDeprecationWarning`. [xordoquy]: https://github.com/xordoquy -[django-python-3]: https://docs.djangoproject.com/en/dev/faq/install/#can-i-use-django-with-python-3 -[porting-python-3]: https://docs.djangoproject.com/en/dev/topics/python3/ -[python-compat]: https://docs.djangoproject.com/en/dev/releases/1.5/#python-compatibility -[django-deprecation-policy]: https://docs.djangoproject.com/en/dev/internals/release-process/#internal-release-deprecation-policy +[django-python-3]: https://docs.djangoproject.com/en/stable/faq/install/#can-i-use-django-with-python-3 +[porting-python-3]: https://docs.djangoproject.com/en/stable/topics/python3/ +[python-compat]: https://docs.djangoproject.com/en/stable/releases/1.5/#python-compatibility +[django-deprecation-policy]: https://docs.djangoproject.com/en/stable/internals/release-process/#internal-release-deprecation-policy [credits]: http://www.django-rest-framework.org/topics/credits [mailing-list]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework [django-rest-framework-docs]: https://github.com/marcgibbons/django-rest-framework-docs diff --git a/docs/topics/2.4-announcement.md b/docs/topics/2.4-announcement.md index 3009daa49..96f68c865 100644 --- a/docs/topics/2.4-announcement.md +++ b/docs/topics/2.4-announcement.md @@ -162,7 +162,7 @@ The next planned release will be 3.0, featuring an improved and simplified seria Once again, many thanks to all the generous [backers and sponsors][kickstarter-sponsors] who've helped make this possible! -[lts-releases]: https://docs.djangoproject.com/en/dev/internals/release-process/#long-term-support-lts-releases +[lts-releases]: https://docs.djangoproject.com/en/stable/internals/release-process/#long-term-support-lts-releases [2-4-release-notes]: release-notes#240 [view-name-and-description-settings]: ../api-guide/settings#view-names-and-descriptions [client-ip-identification]: ../api-guide/throttling#how-clients-are-identified diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md index e6cbf7238..f09788f56 100644 --- a/docs/topics/3.0-announcement.md +++ b/docs/topics/3.0-announcement.md @@ -870,7 +870,7 @@ The `COMPACT_JSON` setting has been added, and can be used to revert this behavi #### File fields as URLs -The `FileField` and `ImageField` classes are now represented as URLs by default. You should ensure you set Django's [standard `MEDIA_URL` setting](https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-MEDIA_URL) appropriately, and ensure your application [serves the uploaded files](https://docs.djangoproject.com/en/dev/howto/static-files/#serving-uploaded-files-in-development). +The `FileField` and `ImageField` classes are now represented as URLs by default. You should ensure you set Django's [standard `MEDIA_URL` setting](https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-MEDIA_URL) appropriately, and ensure your application [serves the uploaded files](https://docs.djangoproject.com/en/stable/howto/static-files/#serving-uploaded-files-in-development). You can revert this behavior, and display filenames in the representation by using the `UPLOADED_FILES_USE_URL` settings key: @@ -894,11 +894,11 @@ If the request is omitted from the context, the returned URLs will be of the for The custom `X-Throttle-Wait-Second` header has now been dropped in favor of the standard `Retry-After` header. You can revert this behavior if needed by writing a custom exception handler for your application. -#### Date and time objects as ISO-8859-1 strings in serializer data. +#### Date and time objects as ISO-8601 strings in serializer data. Date and Time objects are now coerced to strings by default in the serializer output. Previously they were returned as `Date`, `Time` and `DateTime` objects, and later coerced to strings by the renderer. -You can modify this behavior globally by settings the existing `DATE_FORMAT`, `DATETIME_FORMAT` and `TIME_FORMAT` settings keys. Setting these values to `None` instead of their default value of `'iso-8859-1'` will result in native objects being returned in serializer data. +You can modify this behavior globally by settings the existing `DATE_FORMAT`, `DATETIME_FORMAT` and `TIME_FORMAT` settings keys. Setting these values to `None` instead of their default value of `'iso-8601'` will result in native objects being returned in serializer data. REST_FRAMEWORK = { # Return native `Date` and `Time` objects in `serializer.data` @@ -962,4 +962,4 @@ You can follow development on the GitHub site, where we use [milestones to indic [kickstarter]: http://kickstarter.com/projects/tomchristie/django-rest-framework-3 [sponsors]: http://www.django-rest-framework.org/topics/kickstarter-announcement/#sponsors [mixins.py]: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py -[django-localization]: https://docs.djangoproject.com/en/dev/topics/i18n/translation/#localization-how-to-create-language-files +[django-localization]: https://docs.djangoproject.com/en/stable/topics/i18n/translation/#localization-how-to-create-language-files diff --git a/docs/topics/3.1-announcement.md b/docs/topics/3.1-announcement.md index 9eb93fcd7..6cca40665 100644 --- a/docs/topics/3.1-announcement.md +++ b/docs/topics/3.1-announcement.md @@ -153,7 +153,7 @@ For more information, see the documentation on [customizing field mappings][cust We've now moved a number of packages out of the core of REST framework, and into separately installable packages. If you're currently using these you don't need to worry, you simply need to `pip install` the new packages, and change any import paths. -We're making this change in order to help distribute the maintainance workload, and keep better focus of the core essentials of the framework. +We're making this change in order to help distribute the maintenance workload, and keep better focus of the core essentials of the framework. The change also means we can be more flexible with which external packages we recommend. For example, the excellently maintained [Django OAuth toolkit](https://github.com/evonove/django-oauth-toolkit) has now been promoted as our recommended option for integrating OAuth support. diff --git a/docs/topics/3.4-announcement.md b/docs/topics/3.4-announcement.md index 69343c75e..438192c9c 100644 --- a/docs/topics/3.4-announcement.md +++ b/docs/topics/3.4-announcement.md @@ -89,7 +89,7 @@ Name | Support | PyPI pa ---------------------------------|-------------------------------------|-------------------------------- [Core JSON][core-json] | Schema generation & client support. | Built-in support in `coreapi`. [Swagger / OpenAPI][swagger] | Schema generation & client support. | The `openapi-codec` package. -[JSON Hyper-Schema][hyperschema] | Currrently client support only. | The `hyperschema-codec` package. +[JSON Hyper-Schema][hyperschema] | Currently client support only. | The `hyperschema-codec` package. [API Blueprint][api-blueprint] | Not yet available. | Not yet available. --- diff --git a/docs/topics/3.6-announcement.md b/docs/topics/3.6-announcement.md new file mode 100644 index 000000000..f5aeab3e8 --- /dev/null +++ b/docs/topics/3.6-announcement.md @@ -0,0 +1,63 @@ + + +# Django REST framework 3.6 + +--- + +## Funding + +The 3.6 release would not have been possible without our [collaborative funding model][funding]. +If you use REST framework commercially and would like to see this work continue, +we strongly encourage you to invest in its continued development by +**[signing up for a paid plan][funding]**. + + +
+ +*Many thanks to all our [sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), [Machinalis](https://hello.machinalis.co.uk/), [Rollbar](https://rollbar.com), and [MicroPyramid](https://micropyramid.com/django-rest-framework-development-services/).* + + +--- + +## API documentation + +... + +## JavaScript Client + +... + +--- + +## Deprecations + +... + +--- + +[sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors +[funding]: funding.md diff --git a/docs/topics/ajax-csrf-cors.md b/docs/topics/ajax-csrf-cors.md index ad88810da..4960e0881 100644 --- a/docs/topics/ajax-csrf-cors.md +++ b/docs/topics/ajax-csrf-cors.md @@ -35,7 +35,7 @@ The best way to deal with CORS in REST framework is to add the required response [cite]: http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html [csrf]: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) -[csrf-ajax]: https://docs.djangoproject.com/en/dev/ref/csrf/#ajax +[csrf-ajax]: https://docs.djangoproject.com/en/stable/ref/csrf/#ajax [cors]: http://www.w3.org/TR/cors/ [ottoyiu]: https://github.com/ottoyiu/ [django-cors-headers]: https://github.com/ottoyiu/django-cors-headers/ diff --git a/docs/topics/api-clients.md b/docs/topics/api-clients.md index c12551aa6..17721d782 100644 --- a/docs/topics/api-clients.md +++ b/docs/topics/api-clients.md @@ -217,7 +217,7 @@ credentials, headers and bookmarks: # Python client library -The `coreapi` Python package allows you to programatically interact with any +The `coreapi` Python package allows you to programmatically interact with any API that exposes a supported schema format. ## Getting started @@ -304,7 +304,7 @@ other protocols can also be supported. #### Configuring transports -The behaviour of the network layer can be customized by configuring the +The behavior of the network layer can be customized by configuring the transports that the client is instantiated with. import requests @@ -318,6 +318,126 @@ More complex customizations can also be achieved, for example modifying the underlying `requests.Session` instance to [attach transport adaptors][transport-adaptors] that modify the outgoing requests. +--- + +# JavaScript Client Library + +The JavaScript client library allows you to interact with your API either from a browser, or using node. + +## Installing the JavaScript client + +There are two separate JavaScript resources that you need to include in your HTML pages in order to use the JavaScript client library. These are a static `coreapi.js` file, which contains the code for the dynamic client library, and a templated `schema.js` resource, which exposes your API schema. + +First, install the API documentation views. These will include the schema resource that'll allow you to load the schema directly from an HTML page, without having to make an asynchronous AJAX call. + + url(r'^docs/', include_docs_urls(title='My API service')) + +Once the API documentation URLs are installed, you'll be able to include both the required JavaScript resources. Note that the ordering of these two lines is important, as the schema loading requires CoreAPI to already be installed. + + {% load staticfiles %} + + + +The `coreapi` library, and the `schema` object will now both be available on the `window` instance. + + const coreapi = window.coreapi + const schema = window.schema + +## Instantiating a client + + var client = coreapi.Client() + +Header authentication + + var auth = coreapi.auth.HeaderAuthentication({ + value: 'JWT ' + }) + var client = coreapi.Client({auth: auth}) + +Basic authentication + + var auth = coreapi.auth.BasicAuthentication({ + userName: '', + password: '' + }) + var client = coreapi.Client({auth: auth}) + +Session authentication + + // https://docs.djangoproject.com/en/dev/ref/csrf/#ajax + let auth = coreapi.auth.SessionAuthentication({ + csrfHeader: 'X-CSRFToken', + csrfToken: getCookie('csrftoken') + }) + let client = coreapi.Client({auth: auth}) + +## Using the client + +Making requests + + let action = ["users", "list"] + client.action(schema, action).then(function(result) { + // Return value is in 'result' + }) + +Including parameters + + let action = ["users", "create"] + let params = {username: "example", email: "example@example.com"} + client.action(schema, action, params).then(function(result) { + // Return value is in 'result' + }) + +Handling errors + + client.action(schema, action, params).then(function(result) { + // Return value is in 'result' + }).catch(function (error) { + // Error value is in 'error' + }) + +If you're using session authentication, and handling login requests using regular HTML forms then you probably won't need an authentication flow for the client. However, if you're using one of the other types of authentication, + +A suggested pattern for this would be to initially make an unauthenticated client request to an "obtain token" endpoint + +For example, using the "Django REST framework JWT" package + + // Globally accessible state + window.client = coreapi.Client() + window.loggedIn = false + + function loginUser(username, password) { + let action = ["api-token-auth", "obtain-token"] + let params = {username: "example", email: "example@example.com"} + client.action(schema, action, params).then(function(result) { + // On success, instantiate an authenticated client. + let authConfig = {value: 'JWT ' + result['token']} + let auth = window.coreapi.auth.HeaderAuthentication(authConfig) + window.client = coreapi.Client({auth: auth}) + window.loggedIn = true + }).catch(function (error) { + // Handle error case where eg. user provides incorrect credentials. + }) + } + +## Installation with node + +The coreapi package is available on NPM. + + $ npm install coreapi + $ node + const coreapi = require('coreapi') + +You'll either want to include the API schema in your codebase directly, by copying it from the `schema.js` resource, or else load the schema asynchronously. For example: + + let client = new coreapi.Client() + let schema = null + client.get("https://api.example.org/").then(function(data) { + // Load a CoreJSON API schema. + schema = data + console.log('schema loaded') + }) + [heroku-api]: https://devcenter.heroku.com/categories/platform-api [heroku-example]: http://www.coreapi.org/tools-and-resources/example-services/#heroku-json-hyper-schema [core-api]: http://www.coreapi.org/ diff --git a/docs/topics/documenting-your-api.md b/docs/topics/documenting-your-api.md index e7d2cde0c..4f655e3a5 100644 --- a/docs/topics/documenting-your-api.md +++ b/docs/topics/documenting-your-api.md @@ -4,14 +4,73 @@ > > — Roy Fielding, [REST APIs must be hypertext driven][cite] -There are a variety of approaches to API documentation. This document introduces a few of the various tools and options you might choose from. The approaches should not be considered exclusive - you may want to provide more than one documentation style for you API, such as a self describing API that also includes static documentation of the various API endpoints. +REST framework provides built-in support for API documentation. There are also a number of great third-party documentation tools available. -## Endpoint documentation +## Built-in API documentation -The most common way to document Web APIs today is to produce documentation that lists the API endpoints verbatim, and describes the allowable operations on each. There are various tools that allow you to do this in an automated or semi-automated way. +The built-in API documentation includes: + +* Documentation of API endpoints. +* Automatically generated code samples for each of the available API client libraries. +* Support for API interaction. + +### Installation + +To install the API documentation, you'll need to include it in your projects URLconf: + + from rest_framework.documentation import include_docs_urls + + urlpatterns = [ + ... + url(r'^docs/', include_docs_urls(title='My API title')) + ] + +This will include two different views: + + * `/docs/` - The documentation page itself. + * `/docs/schema.js` - A JavaScript resource that exposes the API schema. + +### Documenting your views + +You can document your views by including docstrings that describe each of the available actions. +For example: + + class UserList(generics.ListAPIView): + """ + Return a list of all the existing users. + """" + +If a view supports multiple methods, you should split your documentation using `method:` style delimiters. + + class UserList(generics.ListCreateAPIView): + """ + get: + Return a list of all the existing users. + + post: + Create a new user instance. + """ + +When using viewsets, you should use the relevant action names as delimiters. + + class UserViewSet(viewsets.ModelViewSet): + """ + retrieve: + Return the given user. + + list: + Return a list of all the existing users. + + create: + Create a new user instance. + """ --- +## Third party packages + +There are a number of mature third-party packages for providing API documentation. + #### DRF Docs [DRF Docs][drfdocs-repo] allows you to document Web APIs made with Django REST Framework and it is authored by Emmanouil Konstantinidis. It's made to work out of the box and its setup should not take more than a couple of minutes. Complete documentation can be found on the [website][drfdocs-website] while there is also a [demo][drfdocs-demo] available for people to see what it looks like. **Live API Endpoints** allow you to utilize the endpoints from within the documentation in a neat way. @@ -38,6 +97,34 @@ Both this package and DRF docs are fully documented, well supported, and come hi --- +### DRF AutoDocs + +Oleksander Mashianovs' [DRF Auto Docs][drfautodocs-repo] automated api renderer. + +Collects almost all the code you written into documentation effortlessly. + +Supports: + + * functional view docs + * tree-like structure + * Docstrings: + * markdown + * preserve space & newlines + * formatting with nice syntax + * Fields: + * choices rendering + * help_text (to specify SerializerMethodField output, etc) + * smart read_only/required rendering + * Endpoint properties: + * filter_backends + * authentication_classes + * permission_classes + * extra url params(GET params) + +![whole structure](http://joxi.ru/52aBGNI4k3oyA0.jpg) + +--- + #### Apiary There are various other online tools and services for providing API documentation. One notable service is [Apiary][apiary]. With Apiary, you describe your API using a simple markdown-like syntax. The generated documentation includes API interaction, a mock server for testing & prototyping, and various other tools. @@ -77,7 +164,7 @@ If the python `markdown` library is installed, then [markdown syntax][markdown] [ref]: http://example.com/activating-accounts """ -Note that one constraint of using viewsets is that any documentation be used for all generated views, so for example, you cannot have differing documentation for the generated list view and detail view. +Note that when using viewsets the basic docstring is used for all generated views. To provide descriptions for each view, such as for the the list and retrieve views, use docstring sections as described in [Schemas as documentation: Examples][schemas-examples]. #### The `OPTIONS` method @@ -109,6 +196,7 @@ To implement a hypermedia API you'll need to decide on an appropriate media type [drfdocs-repo]: https://github.com/ekonstantinidis/django-rest-framework-docs [drfdocs-website]: http://www.drfdocs.com/ [drfdocs-demo]: http://demo.drfdocs.com/ +[drfautodocs-repo]: https://github.com/iMakedonsky/drf-autodocs [django-rest-swagger]: https://github.com/marcgibbons/django-rest-swagger [swagger]: https://developers.helloreverb.com/swagger/ [rest-framework-docs]: https://github.com/marcgibbons/django-rest-framework-docs @@ -119,3 +207,4 @@ To implement a hypermedia API you'll need to decide on an appropriate media type [image-django-rest-swagger]: ../img/django-rest-swagger.png [image-apiary]: ../img/apiary.png [image-self-describing-api]: ../img/self-describing.png +[schemas-examples]: ../api-guide/schemas/#examples diff --git a/docs/topics/funding.md b/docs/topics/funding.md index 814de0a3c..91099cb3f 100644 --- a/docs/topics/funding.md +++ b/docs/topics/funding.md @@ -308,7 +308,7 @@ Our professional and premium plans also include **priority support**. At any tim Once you've signed up I'll contact you via email and arrange your ad placements on the site. -For further enquires please contact tom@tomchristie.com. +For further enquires please contact funding@django-rest-framework.org. --- diff --git a/docs/topics/jobs.md b/docs/topics/jobs.md new file mode 100644 index 000000000..53605bd4f --- /dev/null +++ b/docs/topics/jobs.md @@ -0,0 +1,39 @@ +# Jobs + +Looking for a new Django REST Framework related role? On this site we provide a list of job resources that may be helpful. It's also worth checking out if any of [our sponsors are hiring][drf-funding]. + + +## Places to look for Django REST Framework Jobs + +* [https://www.djangoproject.com/community/jobs/][djangoproject-website] +* [https://www.python.org/jobs/][python-org-jobs] +* [https://djangogigs.com][django-gigs-com] +* [https://djangojobs.net/jobs/][django-jobs-net] +* [http://djangojobbers.com][django-jobbers-com] +* [https://www.indeed.com/q-Django-jobs.html][indeed-com] +* [http://stackoverflow.com/jobs/developer-jobs-using-django][stackoverflow-com] +* [https://www.upwork.com/o/jobs/browse/skill/django-framework/][upwork-com] +* [https://www.technojobs.co.uk/django-jobs][technobjobs-co-uk] +* [https://remoteok.io/remote-django-jobs][remoteok-io] +* [https://www.remotepython.com/jobs/][remotepython-com] + + +Know of any other great resources for Django REST Framework jobs that are missing in our list? Please [submit a pull request][submit-pr] or [email us][anna-email]. + +Wonder how else you can help? One of the best ways you can help Django REST Framework is to ask interviewers if their company is signed up for [REST Framework sponsorship][drf-funding] yet. + + +[djangoproject-website]: https://www.djangoproject.com/community/jobs/ +[python-org-jobs]: https://www.python.org/jobs/ +[django-gigs-com]: https://djangogigs.com +[django-jobs-net]: https://djangojobs.net/jobs/ +[django-jobbers-com]: http://djangojobbers.com +[indeed-com]: https://www.indeed.com/q-Django-jobs.html +[stackoverflow-com]: http://stackoverflow.com/jobs/developer-jobs-using-django +[upwork-com]: https://www.upwork.com/o/jobs/browse/skill/django-framework/ +[technobjobs-co-uk]: https://www.technojobs.co.uk/django-jobs +[remoteok-io]: https://remoteok.io/remote-django-jobs +[remotepython-com]: https://www.remotepython.com/jobs/ +[drf-funding]: https://fund.django-rest-framework.org/topics/funding/ +[submit-pr]: https://github.com/tomchristie/django-rest-framework +[anna-email]: mailto:anna@django-rest-framework.org diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 78c5cce6f..6b7b428d1 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -102,7 +102,7 @@ Our gold sponsors include companies large and small. Many thanks for their signi ### Silver sponsors -The serious financial contribution that our silver sponsors have made is very much appreciated. I'd like to say a particular thank you to individuals who have choosen to privately support the project at this level. +The serious financial contribution that our silver sponsors have made is very much appreciated. I'd like to say a particular thank you to individuals who have chosen to privately support the project at this level.