mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-03 05:04:31 +03:00
Version 3.8 Release (#5769)
This commit is contained in:
parent
1befab795a
commit
fc588f539b
|
@ -153,7 +153,7 @@ See the pagination documentation for further guidance on [setting the pagination
|
|||
|
||||
---
|
||||
|
||||
**This setting is pending deprecation.**
|
||||
**This setting has been removed.**
|
||||
|
||||
See the pagination documentation for further guidance on [setting the pagination style](pagination.md#modifying-the-pagination-style).
|
||||
|
||||
|
|
97
docs/topics/3.8-announcement.md
Normal file
97
docs/topics/3.8-announcement.md
Normal file
|
@ -0,0 +1,97 @@
|
|||
<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.8
|
||||
|
||||
The 3.8 release is a maintenance focused release resolving a large number of previously outstanding issues and laying
|
||||
the foundations for future changes.
|
||||
|
||||
---
|
||||
|
||||
## 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]**.
|
||||
|
||||
|
||||
*We'd like to say thanks in particular 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/), and [Rollbar](https://rollbar.com).*
|
||||
|
||||
---
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### Altered the behaviour of `read_only` plus `default` on Field.
|
||||
|
||||
[#5886][gh5886] `read_only` fields will now **always** be excluded from writable fields.
|
||||
|
||||
Previously `read_only` fields when combined with a `default` value would use the `default` for create and update
|
||||
operations. This was counter-intuitive in some circumstances and led to difficulties supporting dotted `source`
|
||||
attributes on nullable relations.
|
||||
|
||||
In order to maintain the old behaviour you may need to pass the value of `read_only` fields when calling `save()` in
|
||||
the view:
|
||||
|
||||
def perform_create(self, serializer):
|
||||
serializer.save(owner=self.request.user)
|
||||
|
||||
Alternatively you may override `save()` or `create()` or `update()` on the serialiser as appropriate.
|
||||
|
||||
---
|
||||
|
||||
## Deprecations
|
||||
|
||||
### `action` decorator replaces `list_route` and `detail_route`
|
||||
|
||||
[#5705][gh5705] `list_route` and `detail_route` have been merge into a single `action` decorator. This improves viewset action introspection, and will allow extra actions to be displayed in the Browsable API in future versions.
|
||||
|
||||
Both `list_route` and `detail_route` are now pending deprecation. They will be deprecated in 3.9 and removed entirely
|
||||
in 3.10.
|
||||
|
||||
The new `action` decorator takes a boolean `detail` argument.
|
||||
|
||||
* Replace `detail_route` uses with `@action(detail=True)`.
|
||||
* Replace `list_route` uses with `@action(detail=False)`.
|
||||
|
||||
|
||||
### `exclude_from_schema`
|
||||
|
||||
Both `APIView.exclude_from_schema` and the `exclude_from_schema` argument to the `@api_view` decorator are now deprecated. They will be removed entirely in 3.9.
|
||||
|
||||
For `APIView` you should instead set a `schema = None` attribute on the view class.
|
||||
|
||||
For function based views the `@schema` decorator can be used to exclude the view from the schema, by using `@schema(None)`.
|
||||
|
||||
---
|
||||
|
||||
## Minor fixes and improvements
|
||||
|
||||
There are a large number of minor fixes and improvements in this release. See the [release notes](release-notes.md) page
|
||||
for a complete listing.
|
||||
|
||||
|
||||
## What's next
|
||||
|
||||
We're currently working towards moving to using [OpenAPI][openapi] as our default schema output. We'll also be revisiting our API documentation generation and client libraries.
|
||||
|
||||
We're doing some consolidation in order to make this happen. It's planned that 3.9 will drop the `coreapi` and `coreschema` libraries, and instead use `apistar` for the API documentation generation, schema generation, and API client libraries.
|
||||
|
||||
[funding]: funding.md
|
||||
[gh5886]: https://github.com/encode/django-rest-framework/issues/5886
|
||||
[gh5705]: https://github.com/encode/django-rest-framework/issues/5705
|
||||
[openapi]: https://www.openapis.org/
|
|
@ -42,7 +42,41 @@ You can determine your currently installed version using `pip show`:
|
|||
|
||||
### 3.8.0
|
||||
|
||||
**Date**: [unreleased][3.8.0-milestone]
|
||||
**Date**: [3rd April 2018][3.8.0-milestone]
|
||||
|
||||
|
||||
* **Breaking Change**: Alter `read_only` plus `default` behaviour. [#5886][gh5886]
|
||||
|
||||
`read_only` fields will now **always** be excluded from writable fields.
|
||||
|
||||
Previously `read_only` fields with a `default` value would use the `default` for create and update operations.
|
||||
|
||||
In order to maintain the old behaviour you may need to pass the value of `read_only` fields when calling `save()` in
|
||||
the view:
|
||||
|
||||
def perform_create(self, serializer):
|
||||
serializer.save(owner=self.request.user)
|
||||
|
||||
Alternatively you may override `save()` or `create()` or `update()` on the serialiser as appropriate.
|
||||
* Correct allow_null behaviour when required=False [#5888][gh5888]
|
||||
|
||||
Without an explicit `default`, `allow_null` implies a default of `null` for outgoing serialisation. Previously such
|
||||
fields were being skipped when read-only or otherwise not required.
|
||||
|
||||
**Possible backwards compatibility break** if you were relying on such fields being excluded from the outgoing
|
||||
representation. In order to restore the old behaviour you can override `data` to exclude the field when `None`.
|
||||
|
||||
For example:
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""
|
||||
Drop `maybe_none` field if None.
|
||||
"""
|
||||
data = super().data()
|
||||
if 'maybe_none' in data and data['maybe_none'] is None:
|
||||
del data['maybe_none']
|
||||
return data
|
||||
|
||||
* Refactor dynamic route generation and improve viewset action introspectibility. [#5705][gh5705]
|
||||
|
||||
|
@ -62,6 +96,61 @@ You can determine your currently installed version using `pip show`:
|
|||
* Deprecated `list_route` & `detail_route` in favor of `action` decorator with `detail` boolean.
|
||||
* Deprecated dynamic list/detail route variants in favor of `DynamicRoute` with `detail` boolean.
|
||||
* Refactored the router's dynamic route generation.
|
||||
* Fix formatting of the 3.7.4 release note [#5704][gh5704]
|
||||
* Docs: Update DRF Writable Nested Serializers references [#5711][gh5711]
|
||||
* Docs: Fixed typo in auth URLs example. [#5713][gh5713]
|
||||
* Improve composite field child errors [#5655][gh5655]
|
||||
* Disable HTML inputs for dict/list fields [#5702][gh5702]
|
||||
* Fix typo in HostNameVersioning doc [#5709][gh5709]
|
||||
* Use rsplit to get module and classname for imports [#5712][gh5712]
|
||||
* Formalize URLPatternsTestCase [#5703][gh5703]
|
||||
* Add exception translation test [#5700][gh5700]
|
||||
* Test staticfiles [#5701][gh5701]
|
||||
* Add drf-yasg to documentation and schema 3rd party packages [#5720][gh5720]
|
||||
* Remove unused `compat._resolve_model()` [#5733][gh5733]
|
||||
* Drop compat workaround for unsupported Python 3.2 [#5734][gh5734]
|
||||
* Prefer `iter(dict)` over `iter(dict.keys())` [#5736][gh5736]
|
||||
* Pass `python_requires` argument to setuptools [#5739][gh5739]
|
||||
* Remove unused links from docs [#5735][gh5735]
|
||||
* Prefer https protocol for links in docs when available [#5729][gh5729]
|
||||
* Add HStoreField, postgres fields tests [#5654][gh5654]
|
||||
* Always fully qualify ValidationError in docs [#5751][gh5751]
|
||||
* Remove unreachable code from ManualSchema [#5766][gh5766]
|
||||
* Allowed customising API documentation code samples [#5752][gh5752]
|
||||
* Updated docs to use `pip show` [#5757][gh5757]
|
||||
* Load 'static' instead of 'staticfiles' in templates [#5773][gh5773]
|
||||
* Fixed a typo in `fields` docs [#5783][gh5783]
|
||||
* Refer to "NamespaceVersioning" instead of "NamespacedVersioning" in the documentation [#5754][gh5754]
|
||||
* ErrorDetail: add `__eq__`/`__ne__` and `__repr__` [#5787][gh5787]
|
||||
* Replace `background-attachment: fixed` in docs [#5777][gh5777]
|
||||
* Make 404 & 403 responses consistent with `exceptions.APIException` output [#5763][gh5763]
|
||||
* Small fix to API documentation: schemas [#5796][gh5796]
|
||||
* Fix schema generation for PrimaryKeyRelatedField [#5764][gh5764]
|
||||
* Represent serializer DictField as an Object in schema [#5765][gh5765]
|
||||
* Added docs example reimplementing ObtainAuthToken [#5802][gh5802]
|
||||
* Add schema to the ObtainAuthToken view [#5676][gh5676]
|
||||
* Fix request formdata handling [#5800][gh5800]
|
||||
* Fix authtoken views imports [#5818][gh5818]
|
||||
* Update pytest, isort [#5815][gh5815] [#5817][gh5817] [#5894][gh5894]
|
||||
* Fixed active timezone handling for non ISO8601 datetimes. [#5833][gh5833]
|
||||
* Made TemplateHTMLRenderer render IntegerField inputs when value is `0`. [#5834][gh5834]
|
||||
* Corrected endpoint in tutorial instructions [#5835][gh5835]
|
||||
* Add Django Rest Framework Role Filters to Third party packages [#5809][gh5809]
|
||||
* Use single copy of static assets. Update jQuery [#5823][gh5823]
|
||||
* Changes ternary conditionals to be PEP308 compliant [#5827][gh5827]
|
||||
* Added links to 'A Todo List API with React' and 'Blog API' tutorials [#5837][gh5837]
|
||||
* Fix comment typo in ModelSerializer [#5844][gh5844]
|
||||
* Add admin to installed apps to avoid test failures. [#5870][gh5870]
|
||||
* Fixed schema for UUIDField in SimpleMetadata. [#5872][gh5872]
|
||||
* Corrected docs on router include with namespaces. [#5843][gh5843]
|
||||
* Test using model objects for dotted source default [#5880][gh5880]
|
||||
* Allow traversing nullable related fields [#5849][gh5849]
|
||||
* Added: Tutorial: Django REST with React (Django 2.0) [#5891][gh5891]
|
||||
* Add `LimitOffsetPagination.get_count` to allow method override [#5846][gh5846]
|
||||
* Don't show hidden fields in metadata [#5854][gh5854]
|
||||
* Enable OrderingFilter to handle an empty tuple (or list) for the 'ordering' field. [#5899][gh5899]
|
||||
* Added generic 500 and 400 JSON error handlers. [#5904][gh5904]
|
||||
|
||||
|
||||
## 3.7.x series
|
||||
|
||||
|
@ -1778,4 +1867,62 @@ For older release notes, [please see the version 2.x documentation][old-release-
|
|||
[gh5697]: https://github.com/encode/django-rest-framework/issues/5697
|
||||
|
||||
<!-- 3.8.0 -->
|
||||
[gh5886]: https://github.com/encode/django-rest-framework/issues/5886
|
||||
[gh5888]: https://github.com/encode/django-rest-framework/issues/5888
|
||||
[gh5705]: https://github.com/encode/django-rest-framework/issues/5705
|
||||
[gh5796]: https://github.com/encode/django-rest-framework/issues/5796
|
||||
[gh5763]: https://github.com/encode/django-rest-framework/issues/5763
|
||||
[gh5777]: https://github.com/encode/django-rest-framework/issues/5777
|
||||
[gh5787]: https://github.com/encode/django-rest-framework/issues/5787
|
||||
[gh5754]: https://github.com/encode/django-rest-framework/issues/5754
|
||||
[gh5783]: https://github.com/encode/django-rest-framework/issues/5783
|
||||
[gh5773]: https://github.com/encode/django-rest-framework/issues/5773
|
||||
[gh5757]: https://github.com/encode/django-rest-framework/issues/5757
|
||||
[gh5752]: https://github.com/encode/django-rest-framework/issues/5752
|
||||
[gh5766]: https://github.com/encode/django-rest-framework/issues/5766
|
||||
[gh5751]: https://github.com/encode/django-rest-framework/issues/5751
|
||||
[gh5654]: https://github.com/encode/django-rest-framework/issues/5654
|
||||
[gh5729]: https://github.com/encode/django-rest-framework/issues/5729
|
||||
[gh5735]: https://github.com/encode/django-rest-framework/issues/5735
|
||||
[gh5739]: https://github.com/encode/django-rest-framework/issues/5739
|
||||
[gh5736]: https://github.com/encode/django-rest-framework/issues/5736
|
||||
[gh5734]: https://github.com/encode/django-rest-framework/issues/5734
|
||||
[gh5733]: https://github.com/encode/django-rest-framework/issues/5733
|
||||
[gh5720]: https://github.com/encode/django-rest-framework/issues/5720
|
||||
[gh5701]: https://github.com/encode/django-rest-framework/issues/5701
|
||||
[gh5700]: https://github.com/encode/django-rest-framework/issues/5700
|
||||
[gh5703]: https://github.com/encode/django-rest-framework/issues/5703
|
||||
[gh5712]: https://github.com/encode/django-rest-framework/issues/5712
|
||||
[gh5709]: https://github.com/encode/django-rest-framework/issues/5709
|
||||
[gh5702]: https://github.com/encode/django-rest-framework/issues/5702
|
||||
[gh5655]: https://github.com/encode/django-rest-framework/issues/5655
|
||||
[gh5713]: https://github.com/encode/django-rest-framework/issues/5713
|
||||
[gh5711]: https://github.com/encode/django-rest-framework/issues/5711
|
||||
[gh5704]: https://github.com/encode/django-rest-framework/issues/5704
|
||||
[gh5854]: https://github.com/encode/django-rest-framework/issues/5854
|
||||
[gh5846]: https://github.com/encode/django-rest-framework/issues/5846
|
||||
[gh5891]: https://github.com/encode/django-rest-framework/issues/5891
|
||||
[gh5849]: https://github.com/encode/django-rest-framework/issues/5849
|
||||
[gh5880]: https://github.com/encode/django-rest-framework/issues/5880
|
||||
[gh5843]: https://github.com/encode/django-rest-framework/issues/5843
|
||||
[gh5872]: https://github.com/encode/django-rest-framework/issues/5872
|
||||
[gh5870]: https://github.com/encode/django-rest-framework/issues/5870
|
||||
[gh5844]: https://github.com/encode/django-rest-framework/issues/5844
|
||||
[gh5837]: https://github.com/encode/django-rest-framework/issues/5837
|
||||
[gh5827]: https://github.com/encode/django-rest-framework/issues/5827
|
||||
[gh5823]: https://github.com/encode/django-rest-framework/issues/5823
|
||||
[gh5809]: https://github.com/encode/django-rest-framework/issues/5809
|
||||
[gh5835]: https://github.com/encode/django-rest-framework/issues/5835
|
||||
[gh5834]: https://github.com/encode/django-rest-framework/issues/5834
|
||||
[gh5833]: https://github.com/encode/django-rest-framework/issues/5833
|
||||
[gh5894]: https://github.com/encode/django-rest-framework/issues/5894
|
||||
[gh5817]: https://github.com/encode/django-rest-framework/issues/5817
|
||||
[gh5815]: https://github.com/encode/django-rest-framework/issues/5815
|
||||
[gh5818]: https://github.com/encode/django-rest-framework/issues/5818
|
||||
[gh5800]: https://github.com/encode/django-rest-framework/issues/5800
|
||||
[gh5676]: https://github.com/encode/django-rest-framework/issues/5676
|
||||
[gh5802]: https://github.com/encode/django-rest-framework/issues/5802
|
||||
[gh5765]: https://github.com/encode/django-rest-framework/issues/5765
|
||||
[gh5764]: https://github.com/encode/django-rest-framework/issues/5764
|
||||
[gh5904]: https://github.com/encode/django-rest-framework/issues/5904
|
||||
[gh5899]: https://github.com/encode/django-rest-framework/issues/5899
|
||||
|
|
|
@ -8,10 +8,10 @@ ______ _____ _____ _____ __
|
|||
"""
|
||||
|
||||
__title__ = 'Django REST framework'
|
||||
__version__ = '3.7.7'
|
||||
__version__ = '3.8.0'
|
||||
__author__ = 'Tom Christie'
|
||||
__license__ = 'BSD 2-Clause'
|
||||
__copyright__ = 'Copyright 2011-2017 Tom Christie'
|
||||
__copyright__ = 'Copyright 2011-2018 Tom Christie'
|
||||
|
||||
# Version synonym
|
||||
VERSION = __version__
|
||||
|
|
|
@ -78,9 +78,9 @@ def api_view(http_method_names=None, exclude_from_schema=False):
|
|||
|
||||
if exclude_from_schema:
|
||||
warnings.warn(
|
||||
"The `exclude_from_schema` argument to `api_view` is pending deprecation. "
|
||||
"The `exclude_from_schema` argument to `api_view` is deprecated. "
|
||||
"Use the `schema` decorator instead, passing `None`.",
|
||||
PendingDeprecationWarning
|
||||
DeprecationWarning
|
||||
)
|
||||
WrappedAPIView.exclude_from_schema = exclude_from_schema
|
||||
|
||||
|
|
|
@ -208,10 +208,10 @@ class EndpointEnumerator(object):
|
|||
return False # Ignore anything except REST framework views.
|
||||
|
||||
if hasattr(callback.cls, 'exclude_from_schema'):
|
||||
fmt = ("The `{}.exclude_from_schema` attribute is pending deprecation. "
|
||||
fmt = ("The `{}.exclude_from_schema` attribute is deprecated. "
|
||||
"Set `schema = None` instead.")
|
||||
msg = fmt.format(callback.cls.__name__)
|
||||
warnings.warn(msg, PendingDeprecationWarning)
|
||||
warnings.warn(msg, DeprecationWarning)
|
||||
if getattr(callback.cls, 'exclude_from_schema', False):
|
||||
return False
|
||||
|
||||
|
|
|
@ -871,15 +871,15 @@ class SchemaGenerationExclusionTests(TestCase):
|
|||
assert should_include == expected
|
||||
|
||||
def test_deprecations(self):
|
||||
with pytest.warns(PendingDeprecationWarning) as record:
|
||||
with pytest.warns(DeprecationWarning) as record:
|
||||
@api_view(["GET"], exclude_from_schema=True)
|
||||
def view(request):
|
||||
pass
|
||||
|
||||
assert len(record) == 1
|
||||
assert str(record[0].message) == (
|
||||
"The `exclude_from_schema` argument to `api_view` is pending "
|
||||
"deprecation. Use the `schema` decorator instead, passing `None`."
|
||||
"The `exclude_from_schema` argument to `api_view` is deprecated. "
|
||||
"Use the `schema` decorator instead, passing `None`."
|
||||
)
|
||||
|
||||
class OldFashionedExcludedView(APIView):
|
||||
|
@ -893,13 +893,13 @@ class SchemaGenerationExclusionTests(TestCase):
|
|||
]
|
||||
|
||||
inspector = EndpointEnumerator(patterns)
|
||||
with pytest.warns(PendingDeprecationWarning) as record:
|
||||
with pytest.warns(DeprecationWarning) as record:
|
||||
inspector.get_api_endpoints()
|
||||
|
||||
assert len(record) == 1
|
||||
assert str(record[0].message) == (
|
||||
"The `OldFashionedExcludedView.exclude_from_schema` attribute is "
|
||||
"pending deprecation. Set `schema = None` instead."
|
||||
"deprecated. Set `schema = None` instead."
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user