Skip to content

Version 3.5 #4525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 54 commits into from
Oct 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
08c7853
Start test case
tomchristie Aug 1, 2016
5abac93
Merge branch 'master' into requests-client
tomchristie Aug 12, 2016
3d1fff3
Added 'requests' test client
tomchristie Aug 15, 2016
e76ca6e
Address typos
tomchristie Aug 15, 2016
6ede654
Graceful fallback if requests is not installed.
tomchristie Aug 17, 2016
049a39e
Add cookie support
tomchristie Aug 17, 2016
64e19c7
Tests for auth and CSRF
tomchristie Aug 17, 2016
da47c34
Py3 compat
tomchristie Aug 17, 2016
5311769
py3 compat
tomchristie Aug 17, 2016
0b3db02
py3 compat
tomchristie Aug 17, 2016
0cc3f50
Add get_requests_client
tomchristie Aug 18, 2016
e4f6928
Added SchemaGenerator.should_include_link
tomchristie Sep 2, 2016
46b9e4e
add settings for html cutoff on related fields
Aug 22, 2016
a556b9c
Router doesn't work if prefix is blank, though project urls.py handle…
c17r Sep 14, 2016
8609c9c
Fix Django 1.10 to-many deprecation
Sep 15, 2016
197b63a
Add django.core.urlresolvers compatibility
Sep 15, 2016
bb37cb7
Update django-filter & django-guardian
Sep 15, 2016
a372a8e
Check for empty router prefix; adjust URL accordingly
c17r Sep 15, 2016
a084924
Fix misc django deprecations
Sep 15, 2016
3bfb0b7
Use TOC extension instead of header
Sep 15, 2016
3bdb0e9
Fix deprecations for py3k
Sep 16, 2016
a0a8b98
Add py3k compatibility to is_simple_callable
Sep 22, 2016
adcf653
Add is_simple_callable tests
Sep 22, 2016
b3afcb2
Drop python 3.2 support (EOL, Dropped by Django)
Sep 22, 2016
b516712
schema_renderers= should *set* the renderers, not append to them.
tomchristie Sep 28, 2016
37b3475
API client (#4424)
tomchristie Sep 29, 2016
c2cec78
Merge master
tomchristie Sep 29, 2016
a60ef8c
Merge branch 'schema-renderers-only-for-root-view' into version-3-5
tomchristie Sep 29, 2016
61b1189
Fix release notes
tomchristie Sep 29, 2016
bc9b522
Merge branch 'rpkilby-fix-simple-callable' into version-3-5
tomchristie Sep 29, 2016
9a4ed1b
Merge branch 'should_include_link' into version-3-5
tomchristie Sep 29, 2016
24bf382
Merge branch 'html_cutoff_settings' of https://github.com/MobileWorks…
tomchristie Sep 29, 2016
f455c67
Merge branch 'MobileWorks-html_cutoff_settings' into version-3-5
tomchristie Sep 29, 2016
b689a3b
Add note about 'User account is disabled.' vs 'Unable to log in'
tomchristie Sep 29, 2016
818ab45
Merge branch 'fix-deprecations' of https://github.com/rpkilby/django-…
tomchristie Sep 29, 2016
ee2b165
Merge branch 'rpkilby-fix-deprecations' into version-3-5
tomchristie Sep 29, 2016
c427144
Merge branch 'router-empty-prefix' of https://github.com/c17r/django-…
tomchristie Sep 29, 2016
49ce3d6
Merge branch 'c17r-router-empty-prefix' into version-3-5
tomchristie Sep 29, 2016
c3a9538
Clean up schema generation (#4527)
tomchristie Sep 30, 2016
4ad5256
Handle multiple methods on custom action (#4529)
tomchristie Sep 30, 2016
8044d38
RequestsClient, CoreAPIClient
tomchristie Oct 4, 2016
a8501f7
exclude_from_schema
tomchristie Oct 5, 2016
cd826ce
Added 'get_schema_view()' shortcut
tomchristie Oct 5, 2016
7e3a3a4
Added schema descriptions
tomchristie Oct 5, 2016
1084dca
Better descriptions for schemas
tomchristie Oct 5, 2016
7edee80
Add type annotation to schema generation
tomchristie Oct 6, 2016
b44ab76
Coerce schema 'pk' in path to actual field name
tomchristie Oct 6, 2016
0724420
Deprecations move into assertion errors
tomchristie Oct 6, 2016
3eb7fe6
Use get_schema_view in tests
tomchristie Oct 7, 2016
5858168
Updte CoreJSON media type
tomchristie Oct 7, 2016
69b4acd
Handle schema structure correctly when path prefixs exist. Closes #4401
tomchristie Oct 7, 2016
fcf932f
Add PendingDeprecation to Router schema generation.
tomchristie Oct 7, 2016
18aebbb
Added SCHEMA_COERCE_PATH_PK and SCHEMA_COERCE_METHOD_NAMES
tomchristie Oct 10, 2016
3f3213b
Renamed and documented 'get_schema_fields' interface.
tomchristie Oct 10, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ env:
- TOX_ENV=py35-django18
- TOX_ENV=py34-django18
- TOX_ENV=py33-django18
- TOX_ENV=py32-django18
- TOX_ENV=py27-django18
- TOX_ENV=py27-django110
- TOX_ENV=py35-django110
Expand Down
6 changes: 6 additions & 0 deletions docs/api-guide/filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,12 @@ Generic filters may also present an interface in the browsable API. To do so you

The method should return a rendered HTML string.

## Pagination & schemas

You can also make the filter controls available to the schema autogeneration
that REST framework provides, by implementing a `get_schema_fields()` method,
which should return a list of `coreapi.Field` instances.

# Third party packages

The following third party packages provide additional filter implementations.
Expand Down
6 changes: 6 additions & 0 deletions docs/api-guide/pagination.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ To have your custom pagination class be used by default, use the `DEFAULT_PAGINA

API responses for list endpoints will now include a `Link` header, instead of including the pagination links as part of the body of the response, for example:

## Pagination & schemas

You can also make the pagination controls available to the schema autogeneration
that REST framework provides, by implementing a `get_schema_fields()` method,
which should return a list of `coreapi.Field` instances.

---

![Link Header][link-header]
Expand Down
2 changes: 2 additions & 0 deletions docs/api-guide/relations.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,8 @@ There are two keyword arguments you can use to control this behavior:
- `html_cutoff` - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Set to `None` to disable any limiting. Defaults to `1000`.
- `html_cutoff_text` - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to `"More than {count} items…"`

You can also control these globally using the settings `HTML_SELECT_CUTOFF` and `HTML_SELECT_CUTOFF_TEXT`.

In cases where the cutoff is being enforced you may want to instead use a plain input field in the HTML form. You can do so using the `style` keyword argument. For example:

assigned_to = serializers.SlugRelatedField(
Expand Down
4 changes: 2 additions & 2 deletions docs/api-guide/reverse.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ There's no requirement for you to use them, but if you do then the self-describi

**Signature:** `reverse(viewname, *args, **kwargs)`

Has the same behavior as [`django.core.urlresolvers.reverse`][reverse], except that it returns a fully qualified URL, using the request to determine the host and port.
Has the same behavior as [`django.urls.reverse`][reverse], except that it returns a fully qualified URL, using the request to determine the host and port.

You should **include the request as a keyword argument** to the function, for example:

Expand All @@ -44,7 +44,7 @@ You should **include the request as a keyword argument** to the function, for ex

**Signature:** `reverse_lazy(viewname, *args, **kwargs)`

Has the same behavior as [`django.core.urlresolvers.reverse_lazy`][reverse-lazy], except that it returns a fully qualified URL, using the request to determine the host and port.
Has the same behavior as [`django.urls.reverse_lazy`][reverse-lazy], except that it returns a fully qualified URL, using the request to determine the host and port.

As with the `reverse` function, you should **include the request as a keyword argument** to the function, for example:

Expand Down
138 changes: 101 additions & 37 deletions docs/api-guide/schemas.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,20 @@ REST framework includes functionality for auto-generating a schema,
or allows you to specify one explicitly. There are a few different ways to
add a schema to your API, depending on exactly what you need.

## Using DefaultRouter
## The get_schema_view shortcut

If you're using `DefaultRouter` then you can include an auto-generated schema,
simply by adding a `schema_title` argument to the router.
The simplest way to include a schema in your project is to use the
`get_schema_view()` function.

router = DefaultRouter(schema_title='Server Monitoring API')
schema_view = get_schema_view(title="Server Monitoring API")

The schema will be included at the root URL, `/`, and presented to clients
that include the Core JSON media type in their `Accept` header.
urlpatterns = [
url('^$', schema_view),
...
]

Once the view has been added, you'll be able to make API requests to retrieve
the auto-generated schema definition.

$ http http://127.0.0.1:8000/ Accept:application/vnd.coreapi+json
HTTP/1.0 200 OK
Expand All @@ -125,48 +130,43 @@ that include the Core JSON media type in their `Accept` header.
...
}

This is a great zero-configuration option for when you want to get up and
running really quickly.

The other available options to `DefaultRouter` are:
The arguments to `get_schema_view()` are:

#### schema_renderers

May be used to pass the set of renderer classes that can be used to render schema output.

from rest_framework.renderers import CoreJSONRenderer
from my_custom_package import APIBlueprintRenderer
#### `title`

router = DefaultRouter(schema_title='Server Monitoring API', schema_renderers=[
CoreJSONRenderer, APIBlueprintRenderer
])
May be used to provide a descriptive title for the schema definition.

#### schema_url
#### `url`

May be used to pass the root URL for the schema. This can either be used to ensure that
the schema URLs include a canonical hostname and schema, or to ensure that all the
schema URLs include a path prefix.
May be used to pass a canonical URL for the schema.

router = DefaultRouter(
schema_title='Server Monitoring API',
schema_url='https://www.example.org/api/'
schema_view = get_schema_view(
title='Server Monitoring API',
url='https://www.example.org/api/'
)

If you want more flexibility over the schema output then you'll need to consider
using `SchemaGenerator` instead.

#### root_renderers
#### `renderer_classes`

May be used to pass the set of renderer classes that can be used to render the API root endpoint.

## Using SchemaGenerator
from rest_framework.renderers import CoreJSONRenderer
from my_custom_package import APIBlueprintRenderer

The most common way to add a schema to your API is to use the `SchemaGenerator`
class to auto-generate the `Document` instance, and to return that from a view.
schema_view = get_schema_view(
title='Server Monitoring API',
url='https://www.example.org/api/',
renderer_classes=[CoreJSONRenderer, APIBlueprintRenderer]
)

## Using an explicit schema view

If you need a little more control than the `get_schema_view()` shortcut gives you,
then you can use the `SchemaGenerator` class directly to auto-generate the
`Document` instance, and to return that from a view.

This option gives you the flexibility of setting up the schema endpoint
with whatever behavior you want. For example, you can apply different
permission, throttling or authentication policies to the schema endpoint.
with whatever behaviour you want. For example, you can apply different
permission, throttling, or authentication policies to the schema endpoint.

Here's an example of using `SchemaGenerator` together with a view to
return the schema.
Expand All @@ -176,12 +176,13 @@ return the schema.
from rest_framework.decorators import api_view, renderer_classes
from rest_framework import renderers, response, schemas

generator = schemas.SchemaGenerator(title='Bookings API')

@api_view()
@renderer_classes([renderers.CoreJSONRenderer])
def schema_view(request):
generator = schemas.SchemaGenerator(title='Bookings API')
return response.Response(generator.get_schema())
schema = generator.get_schema(request)
return response.Response(schema)

**urls.py:**

Expand Down Expand Up @@ -241,6 +242,69 @@ You could then either:

---

# Schemas as documentation

One common usage of API schemas is to use them to build documentation pages.

The schema generation in REST framework uses docstrings to automatically
populate descriptions in the schema document.

These descriptions will be based on:

* The corresponding method docstring if one exists.
* A named section within the class docstring, which can be either single line or multi-line.
* The class docstring.

## Examples

An `APIView`, with an explicit method docstring.

class ListUsernames(APIView):
def get(self, request):
"""
Return a list of all user names in the system.
"""
usernames = [user.username for user in User.objects.all()]
return Response(usernames)

A `ViewSet`, with an explict action docstring.

class ListUsernames(ViewSet):
def list(self, request):
"""
Return a list of all user names in the system.
"""
usernames = [user.username for user in User.objects.all()]
return Response(usernames)

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.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAdminUser,)

A generic viewset with sections in the class docstring, using multi-line style.

class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.

retrieve:
Return a user instance.

list:
Return all users, ordered by most recently joined.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer

---

# Alternate schema formats

In order to support an alternate schema format, you need to implement a custom renderer
Expand Down
38 changes: 38 additions & 0 deletions docs/api-guide/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,28 @@ Default:

---

## Schema generation controls

#### SCHEMA_COERCE_PATH_PK

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.

Default: `True`

#### SCHEMA_COERCE_METHOD_NAMES

If set, this is used to map internal viewset method names onto external action
names used in the schema generation. This allows us to generate names that
are more suitable for an external representation than those that are used
internally in the codebase.

Default: `{'retrieve': 'read', 'destroy': 'delete'}`

---

## Content type controls

#### URL_FORMAT_OVERRIDE
Expand Down Expand Up @@ -382,6 +404,22 @@ This should be a function with the following signature:

Default: `'rest_framework.views.get_view_description'`

## HTML Select Field cutoffs

Global settings for [select field cutoffs for rendering relational fields](relations.md#select-field-cutoffs) in the browsable API.

#### HTML_SELECT_CUTOFF

Global setting for the `html_cutoff` value. Must be an integer.

Default: 1000

#### HTML_SELECT_CUTOFF_TEXT

A string representing a global setting for `html_cutoff_text`.

Default: `"More than {count} items..."`

---

## Miscellaneous settings
Expand Down
Loading