mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-14 13:46:59 +03:00
99ca078ebb
* Add 'Community' tab to navigation, move articles * Drop DRF 2.x announcements and the docs note * Drop embedded tutorial/guide/topics links * Conver mixture of tabs/spaces => spaces * Fix topics/community links
267 lines
9.8 KiB
Markdown
267 lines
9.8 KiB
Markdown
<style>
|
|
.promo li a {
|
|
float: left;
|
|
width: 130px;
|
|
height: 20px;
|
|
text-align: center;
|
|
margin: 10px 30px;
|
|
padding: 150px 0 0 0;
|
|
background-position: 0 50%;
|
|
background-size: 130px auto;
|
|
background-repeat: no-repeat;
|
|
font-size: 120%;
|
|
color: black;
|
|
}
|
|
.promo li {
|
|
list-style: none;
|
|
}
|
|
</style>
|
|
|
|
# Django REST framework 3.5
|
|
|
|
The 3.5 release is the second in a planned series that is addressing schema
|
|
generation, hypermedia support, API client libraries, and finally realtime support.
|
|
|
|
---
|
|
|
|
## Funding
|
|
|
|
The 3.5 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]**.
|
|
|
|
<ul class="premium-promo promo">
|
|
<li><a href="http://jobs.rover.com/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/rover_130x130.png)">Rover.com</a></li>
|
|
<li><a href="https://getsentry.com/welcome/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/sentry130.png)">Sentry</a></li>
|
|
<li><a href="https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/stream-130.png)">Stream</a></li>
|
|
<li><a href="https://www.machinalis.com/#services" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/Machinalis130.png)">Machinalis</a></li>
|
|
</ul>
|
|
<div style="clear: both; padding-bottom: 20px;"></div>
|
|
|
|
*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), and [Machinalis](https://www.machinalis.com/#services).*
|
|
|
|
---
|
|
|
|
## Improved schema generation
|
|
|
|
Docstrings on views are now pulled through into schema definitions, allowing
|
|
you to [use the schema definition to document your API][schema-docs].
|
|
|
|
There is now also a shortcut function, `get_schema_view()`, which makes it easier to
|
|
[adding schema views][schema-view] to your API.
|
|
|
|
For example, to include a swagger schema to your API, you would do the following:
|
|
|
|
* Run `pip install django-rest-swagger`.
|
|
|
|
* Add `'rest_framework_swagger'` to your `INSTALLED_APPS` setting.
|
|
|
|
* Include the schema view in your URL conf:
|
|
|
|
```py
|
|
from rest_framework.schemas import get_schema_view
|
|
from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer
|
|
|
|
schema_view = get_schema_view(
|
|
title='Example API',
|
|
renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer]
|
|
)
|
|
|
|
urlpatterns = [
|
|
url(r'^swagger/$', schema_view),
|
|
...
|
|
]
|
|
```
|
|
|
|
There have been a large number of fixes to the schema generation. These should
|
|
resolve issues for anyone using the latest version of the `django-rest-swagger`
|
|
package.
|
|
|
|
Some of these changes do affect the resulting schema structure,
|
|
so if you're already using schema generation you should make sure to review
|
|
[the deprecation notes](#deprecations), particularly if you're currently using
|
|
a dynamic client library to interact with your API.
|
|
|
|
Finally, we're also now exposing the schema generation as a
|
|
[publicly documented API][schema-generation-api], allowing you to more easily
|
|
override the behaviour.
|
|
|
|
## Requests test client
|
|
|
|
You can now test your project using the `requests` library.
|
|
|
|
This exposes exactly the same interface as if you were using a standard
|
|
requests session instance.
|
|
|
|
client = RequestsClient()
|
|
response = client.get('http://testserver/users/')
|
|
assert response.status_code == 200
|
|
|
|
Rather than sending any HTTP requests to the network, this interface will
|
|
coerce all outgoing requests into WSGI, and call into your application directly.
|
|
|
|
## Core API client
|
|
|
|
You can also now test your project by interacting with it using the `coreapi`
|
|
client library.
|
|
|
|
# Fetch the API schema
|
|
client = CoreAPIClient()
|
|
schema = client.get('http://testserver/schema/')
|
|
|
|
# Create a new organisation
|
|
params = {'name': 'MegaCorp', 'status': 'active'}
|
|
client.action(schema, ['organisations', 'create'], params)
|
|
|
|
# Ensure that the organisation exists in the listing
|
|
data = client.action(schema, ['organisations', 'list'])
|
|
assert(len(data) == 1)
|
|
assert(data == [{'name': 'MegaCorp', 'status': 'active'}])
|
|
|
|
Again, this will call directly into the application using the WSGI interface,
|
|
rather than making actual network calls.
|
|
|
|
This is a good option if you are planning for clients to mainly interact with
|
|
your API using the `coreapi` client library, or some other auto-generated client.
|
|
|
|
## Live tests
|
|
|
|
One interesting aspect of both the `requests` client and the `coreapi` client
|
|
is that they allow you to write tests in such a way that they can also be made
|
|
to run against a live service.
|
|
|
|
By switching the WSGI based client instances to actual instances of `requests.Session`
|
|
or `coreapi.Client` you can have the test cases make actual network calls.
|
|
|
|
Being able to write test cases that can exercise your staging or production
|
|
environment is a powerful tool. However in order to do this, you'll need to pay
|
|
close attention to how you handle setup and teardown to ensure a strict isolation
|
|
of test data from other live or staging data.
|
|
|
|
## RAML support
|
|
|
|
We now have preliminary support for [RAML documentation generation][django-rest-raml].
|
|
|
|
![RAML Example][raml-image]
|
|
|
|
Further work on the encoding and documentation generation is planned, in order to
|
|
make features such as the 'Try it now' support available at a later date.
|
|
|
|
This work also now means that you can use the Core API client libraries to interact
|
|
with APIs that expose a RAML specification. The [RAML codec][raml-codec] gives some examples of
|
|
interacting with the Spotify API in this way.
|
|
|
|
## Validation codes
|
|
|
|
Exceptions raised by REST framework now include short code identifiers.
|
|
When used together with our customizable error handling, this now allows you to
|
|
modify the style of API error messages.
|
|
|
|
As an example, this allows for the following style of error responses:
|
|
|
|
{
|
|
"message": "You do not have permission to perform this action.",
|
|
"code": "permission_denied"
|
|
}
|
|
|
|
This is particularly useful with validation errors, which use appropriate
|
|
codes to identify differing kinds of failure...
|
|
|
|
{
|
|
"name": {"message": "This field is required.", "code": "required"},
|
|
"age": {"message": "A valid integer is required.", "code": "invalid"}
|
|
}
|
|
|
|
## Client upload & download support
|
|
|
|
The Python `coreapi` client library and the Core API command line tool both
|
|
now fully support file [uploads][uploads] and [downloads][downloads].
|
|
|
|
---
|
|
|
|
## Deprecations
|
|
|
|
### Generating schemas from Router
|
|
|
|
The router arguments for generating a schema view, such as `schema_title`,
|
|
are now pending deprecation.
|
|
|
|
Instead of using `DefaultRouter(schema_title='Example API')`, you should use
|
|
the `get_schema_view()` function, and include the view in your URL conf.
|
|
|
|
Make sure to include the view before your router urls. For example:
|
|
|
|
from rest_framework.schemas import get_schema_view
|
|
from my_project.routers import router
|
|
|
|
schema_view = get_schema_view(title='Example API')
|
|
|
|
urlpatterns = [
|
|
url('^$', schema_view),
|
|
url(r'^', include(router.urls)),
|
|
]
|
|
|
|
### Schema path representations
|
|
|
|
The `'pk'` identifier in schema paths is now mapped onto the actually model field
|
|
name by default. This will typically be `'id'`.
|
|
|
|
This gives a better external representation for schemas, with less implementation
|
|
detail being exposed. It also reflects the behaviour of using a ModelSerializer
|
|
class with `fields = '__all__'`.
|
|
|
|
You can revert to the previous behaviour by setting `'SCHEMA_COERCE_PATH_PK': False`
|
|
in the REST framework settings.
|
|
|
|
### Schema action name representations
|
|
|
|
The internal `retrieve()` and `destroy()` method names are now coerced to an
|
|
external representation of `read` and `delete`.
|
|
|
|
You can revert to the previous behaviour by setting `'SCHEMA_COERCE_METHOD_NAMES': {}`
|
|
in the REST framework settings.
|
|
|
|
### DjangoFilterBackend
|
|
|
|
The functionality of the built-in `DjangoFilterBackend` is now completely
|
|
included by the `django-filter` package.
|
|
|
|
You should change your imports and REST framework filter settings as follows:
|
|
|
|
* `rest_framework.filters.DjangoFilterBackend` becomes `django_filters.rest_framework.DjangoFilterBackend`.
|
|
* `rest_framework.filters.FilterSet` becomes `django_filters.rest_framework.FilterSet`.
|
|
|
|
The existing imports will continue to work but are now pending deprecation.
|
|
|
|
### CoreJSON media type
|
|
|
|
The media type for `CoreJSON` is now `application/json+coreapi`, rather than
|
|
the previous `application/vnd.json+coreapi`. This brings it more into line with
|
|
other custom media types, such as those used by Swagger and RAML.
|
|
|
|
The clients currently accept either media type. The old style-media type will
|
|
be deprecated at a later date.
|
|
|
|
### ModelSerializer 'fields' and 'exclude'
|
|
|
|
ModelSerializer and HyperlinkedModelSerializer must include either a fields
|
|
option, or an exclude option. The `fields = '__all__'` shortcut may be used to
|
|
explicitly include all fields.
|
|
|
|
Failing to set either `fields` or `exclude` raised a pending deprecation warning
|
|
in version 3.3 and raised a deprecation warning in 3.4. Its usage is now mandatory.
|
|
|
|
---
|
|
|
|
[sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors
|
|
[funding]: funding.md
|
|
[uploads]: https://core-api.github.io/python-client/api-guide/utils/#file
|
|
[downloads]: https://core-api.github.io/python-client/api-guide/codecs/#downloadcodec
|
|
[schema-generation-api]: ../api-guide/schemas/#schemagenerator
|
|
[schema-docs]: ../api-guide/schemas/#schemas-as-documentation
|
|
[schema-view]: ../api-guide/schemas/#the-get_schema_view-shortcut
|
|
[django-rest-raml]: https://github.com/encode/django-rest-raml
|
|
[raml-image]: ../img/raml.png
|
|
[raml-codec]: https://github.com/core-api/python-raml-codec
|