Skip to content

Commit fc588f5

Browse files
Version 3.8 Release (#5769)
1 parent 1befab7 commit fc588f5

File tree

7 files changed

+257
-13
lines changed

7 files changed

+257
-13
lines changed

Diff for: docs/api-guide/settings.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ See the pagination documentation for further guidance on [setting the pagination
153153

154154
---
155155

156-
**This setting is pending deprecation.**
156+
**This setting has been removed.**
157157

158158
See the pagination documentation for further guidance on [setting the pagination style](pagination.md#modifying-the-pagination-style).
159159

Diff for: docs/topics/3.8-announcement.md

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<style>
2+
.promo li a {
3+
float: left;
4+
width: 130px;
5+
height: 20px;
6+
text-align: center;
7+
margin: 10px 30px;
8+
padding: 150px 0 0 0;
9+
background-position: 0 50%;
10+
background-size: 130px auto;
11+
background-repeat: no-repeat;
12+
font-size: 120%;
13+
color: black;
14+
}
15+
.promo li {
16+
list-style: none;
17+
}
18+
</style>
19+
20+
# Django REST framework 3.8
21+
22+
The 3.8 release is a maintenance focused release resolving a large number of previously outstanding issues and laying
23+
the foundations for future changes.
24+
25+
---
26+
27+
## Funding
28+
29+
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
30+
**[signing up for a paid&nbsp;plan][funding]**.
31+
32+
33+
*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).*
34+
35+
---
36+
37+
## Breaking Changes
38+
39+
### Altered the behaviour of `read_only` plus `default` on Field.
40+
41+
[#5886][gh5886] `read_only` fields will now **always** be excluded from writable fields.
42+
43+
Previously `read_only` fields when combined with a `default` value would use the `default` for create and update
44+
operations. This was counter-intuitive in some circumstances and led to difficulties supporting dotted `source`
45+
attributes on nullable relations.
46+
47+
In order to maintain the old behaviour you may need to pass the value of `read_only` fields when calling `save()` in
48+
the view:
49+
50+
def perform_create(self, serializer):
51+
serializer.save(owner=self.request.user)
52+
53+
Alternatively you may override `save()` or `create()` or `update()` on the serialiser as appropriate.
54+
55+
---
56+
57+
## Deprecations
58+
59+
### `action` decorator replaces `list_route` and `detail_route`
60+
61+
[#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.
62+
63+
Both `list_route` and `detail_route` are now pending deprecation. They will be deprecated in 3.9 and removed entirely
64+
in 3.10.
65+
66+
The new `action` decorator takes a boolean `detail` argument.
67+
68+
* Replace `detail_route` uses with `@action(detail=True)`.
69+
* Replace `list_route` uses with `@action(detail=False)`.
70+
71+
72+
### `exclude_from_schema`
73+
74+
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.
75+
76+
For `APIView` you should instead set a `schema = None` attribute on the view class.
77+
78+
For function based views the `@schema` decorator can be used to exclude the view from the schema, by using `@schema(None)`.
79+
80+
---
81+
82+
## Minor fixes and improvements
83+
84+
There are a large number of minor fixes and improvements in this release. See the [release notes](release-notes.md) page
85+
for a complete listing.
86+
87+
88+
## What's next
89+
90+
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.
91+
92+
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.
93+
94+
[funding]: funding.md
95+
[gh5886]: https://github.com/encode/django-rest-framework/issues/5886
96+
[gh5705]: https://github.com/encode/django-rest-framework/issues/5705
97+
[openapi]: https://www.openapis.org/

Diff for: docs/topics/release-notes.md

+148-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,41 @@ You can determine your currently installed version using `pip show`:
4242

4343
### 3.8.0
4444

45-
**Date**: [unreleased][3.8.0-milestone]
45+
**Date**: [3rd April 2018][3.8.0-milestone]
46+
47+
48+
* **Breaking Change**: Alter `read_only` plus `default` behaviour. [#5886][gh5886]
49+
50+
`read_only` fields will now **always** be excluded from writable fields.
51+
52+
Previously `read_only` fields with a `default` value would use the `default` for create and update operations.
53+
54+
In order to maintain the old behaviour you may need to pass the value of `read_only` fields when calling `save()` in
55+
the view:
56+
57+
def perform_create(self, serializer):
58+
serializer.save(owner=self.request.user)
59+
60+
Alternatively you may override `save()` or `create()` or `update()` on the serialiser as appropriate.
61+
* Correct allow_null behaviour when required=False [#5888][gh5888]
62+
63+
Without an explicit `default`, `allow_null` implies a default of `null` for outgoing serialisation. Previously such
64+
fields were being skipped when read-only or otherwise not required.
65+
66+
**Possible backwards compatibility break** if you were relying on such fields being excluded from the outgoing
67+
representation. In order to restore the old behaviour you can override `data` to exclude the field when `None`.
68+
69+
For example:
70+
71+
@property
72+
def data(self):
73+
"""
74+
Drop `maybe_none` field if None.
75+
"""
76+
data = super().data()
77+
if 'maybe_none' in data and data['maybe_none'] is None:
78+
del data['maybe_none']
79+
return data
4680

4781
* Refactor dynamic route generation and improve viewset action introspectibility. [#5705][gh5705]
4882

@@ -62,6 +96,61 @@ You can determine your currently installed version using `pip show`:
6296
* Deprecated `list_route` & `detail_route` in favor of `action` decorator with `detail` boolean.
6397
* Deprecated dynamic list/detail route variants in favor of `DynamicRoute` with `detail` boolean.
6498
* Refactored the router's dynamic route generation.
99+
* Fix formatting of the 3.7.4 release note [#5704][gh5704]
100+
* Docs: Update DRF Writable Nested Serializers references [#5711][gh5711]
101+
* Docs: Fixed typo in auth URLs example. [#5713][gh5713]
102+
* Improve composite field child errors [#5655][gh5655]
103+
* Disable HTML inputs for dict/list fields [#5702][gh5702]
104+
* Fix typo in HostNameVersioning doc [#5709][gh5709]
105+
* Use rsplit to get module and classname for imports [#5712][gh5712]
106+
* Formalize URLPatternsTestCase [#5703][gh5703]
107+
* Add exception translation test [#5700][gh5700]
108+
* Test staticfiles [#5701][gh5701]
109+
* Add drf-yasg to documentation and schema 3rd party packages [#5720][gh5720]
110+
* Remove unused `compat._resolve_model()` [#5733][gh5733]
111+
* Drop compat workaround for unsupported Python 3.2 [#5734][gh5734]
112+
* Prefer `iter(dict)` over `iter(dict.keys())` [#5736][gh5736]
113+
* Pass `python_requires` argument to setuptools [#5739][gh5739]
114+
* Remove unused links from docs [#5735][gh5735]
115+
* Prefer https protocol for links in docs when available [#5729][gh5729]
116+
* Add HStoreField, postgres fields tests [#5654][gh5654]
117+
* Always fully qualify ValidationError in docs [#5751][gh5751]
118+
* Remove unreachable code from ManualSchema [#5766][gh5766]
119+
* Allowed customising API documentation code samples [#5752][gh5752]
120+
* Updated docs to use `pip show` [#5757][gh5757]
121+
* Load 'static' instead of 'staticfiles' in templates [#5773][gh5773]
122+
* Fixed a typo in `fields` docs [#5783][gh5783]
123+
* Refer to "NamespaceVersioning" instead of "NamespacedVersioning" in the documentation [#5754][gh5754]
124+
* ErrorDetail: add `__eq__`/`__ne__` and `__repr__` [#5787][gh5787]
125+
* Replace `background-attachment: fixed` in docs [#5777][gh5777]
126+
* Make 404 & 403 responses consistent with `exceptions.APIException` output [#5763][gh5763]
127+
* Small fix to API documentation: schemas [#5796][gh5796]
128+
* Fix schema generation for PrimaryKeyRelatedField [#5764][gh5764]
129+
* Represent serializer DictField as an Object in schema [#5765][gh5765]
130+
* Added docs example reimplementing ObtainAuthToken [#5802][gh5802]
131+
* Add schema to the ObtainAuthToken view [#5676][gh5676]
132+
* Fix request formdata handling [#5800][gh5800]
133+
* Fix authtoken views imports [#5818][gh5818]
134+
* Update pytest, isort [#5815][gh5815] [#5817][gh5817] [#5894][gh5894]
135+
* Fixed active timezone handling for non ISO8601 datetimes. [#5833][gh5833]
136+
* Made TemplateHTMLRenderer render IntegerField inputs when value is `0`. [#5834][gh5834]
137+
* Corrected endpoint in tutorial instructions [#5835][gh5835]
138+
* Add Django Rest Framework Role Filters to Third party packages [#5809][gh5809]
139+
* Use single copy of static assets. Update jQuery [#5823][gh5823]
140+
* Changes ternary conditionals to be PEP308 compliant [#5827][gh5827]
141+
* Added links to 'A Todo List API with React' and 'Blog API' tutorials [#5837][gh5837]
142+
* Fix comment typo in ModelSerializer [#5844][gh5844]
143+
* Add admin to installed apps to avoid test failures. [#5870][gh5870]
144+
* Fixed schema for UUIDField in SimpleMetadata. [#5872][gh5872]
145+
* Corrected docs on router include with namespaces. [#5843][gh5843]
146+
* Test using model objects for dotted source default [#5880][gh5880]
147+
* Allow traversing nullable related fields [#5849][gh5849]
148+
* Added: Tutorial: Django REST with React (Django 2.0) [#5891][gh5891]
149+
* Add `LimitOffsetPagination.get_count` to allow method override [#5846][gh5846]
150+
* Don't show hidden fields in metadata [#5854][gh5854]
151+
* Enable OrderingFilter to handle an empty tuple (or list) for the 'ordering' field. [#5899][gh5899]
152+
* Added generic 500 and 400 JSON error handlers. [#5904][gh5904]
153+
65154

66155
## 3.7.x series
67156

@@ -1778,4 +1867,62 @@ For older release notes, [please see the version 2.x documentation][old-release-
17781867
[gh5697]: https://github.com/encode/django-rest-framework/issues/5697
17791868

17801869
<!-- 3.8.0 -->
1870+
[gh5886]: https://github.com/encode/django-rest-framework/issues/5886
1871+
[gh5888]: https://github.com/encode/django-rest-framework/issues/5888
17811872
[gh5705]: https://github.com/encode/django-rest-framework/issues/5705
1873+
[gh5796]: https://github.com/encode/django-rest-framework/issues/5796
1874+
[gh5763]: https://github.com/encode/django-rest-framework/issues/5763
1875+
[gh5777]: https://github.com/encode/django-rest-framework/issues/5777
1876+
[gh5787]: https://github.com/encode/django-rest-framework/issues/5787
1877+
[gh5754]: https://github.com/encode/django-rest-framework/issues/5754
1878+
[gh5783]: https://github.com/encode/django-rest-framework/issues/5783
1879+
[gh5773]: https://github.com/encode/django-rest-framework/issues/5773
1880+
[gh5757]: https://github.com/encode/django-rest-framework/issues/5757
1881+
[gh5752]: https://github.com/encode/django-rest-framework/issues/5752
1882+
[gh5766]: https://github.com/encode/django-rest-framework/issues/5766
1883+
[gh5751]: https://github.com/encode/django-rest-framework/issues/5751
1884+
[gh5654]: https://github.com/encode/django-rest-framework/issues/5654
1885+
[gh5729]: https://github.com/encode/django-rest-framework/issues/5729
1886+
[gh5735]: https://github.com/encode/django-rest-framework/issues/5735
1887+
[gh5739]: https://github.com/encode/django-rest-framework/issues/5739
1888+
[gh5736]: https://github.com/encode/django-rest-framework/issues/5736
1889+
[gh5734]: https://github.com/encode/django-rest-framework/issues/5734
1890+
[gh5733]: https://github.com/encode/django-rest-framework/issues/5733
1891+
[gh5720]: https://github.com/encode/django-rest-framework/issues/5720
1892+
[gh5701]: https://github.com/encode/django-rest-framework/issues/5701
1893+
[gh5700]: https://github.com/encode/django-rest-framework/issues/5700
1894+
[gh5703]: https://github.com/encode/django-rest-framework/issues/5703
1895+
[gh5712]: https://github.com/encode/django-rest-framework/issues/5712
1896+
[gh5709]: https://github.com/encode/django-rest-framework/issues/5709
1897+
[gh5702]: https://github.com/encode/django-rest-framework/issues/5702
1898+
[gh5655]: https://github.com/encode/django-rest-framework/issues/5655
1899+
[gh5713]: https://github.com/encode/django-rest-framework/issues/5713
1900+
[gh5711]: https://github.com/encode/django-rest-framework/issues/5711
1901+
[gh5704]: https://github.com/encode/django-rest-framework/issues/5704
1902+
[gh5854]: https://github.com/encode/django-rest-framework/issues/5854
1903+
[gh5846]: https://github.com/encode/django-rest-framework/issues/5846
1904+
[gh5891]: https://github.com/encode/django-rest-framework/issues/5891
1905+
[gh5849]: https://github.com/encode/django-rest-framework/issues/5849
1906+
[gh5880]: https://github.com/encode/django-rest-framework/issues/5880
1907+
[gh5843]: https://github.com/encode/django-rest-framework/issues/5843
1908+
[gh5872]: https://github.com/encode/django-rest-framework/issues/5872
1909+
[gh5870]: https://github.com/encode/django-rest-framework/issues/5870
1910+
[gh5844]: https://github.com/encode/django-rest-framework/issues/5844
1911+
[gh5837]: https://github.com/encode/django-rest-framework/issues/5837
1912+
[gh5827]: https://github.com/encode/django-rest-framework/issues/5827
1913+
[gh5823]: https://github.com/encode/django-rest-framework/issues/5823
1914+
[gh5809]: https://github.com/encode/django-rest-framework/issues/5809
1915+
[gh5835]: https://github.com/encode/django-rest-framework/issues/5835
1916+
[gh5834]: https://github.com/encode/django-rest-framework/issues/5834
1917+
[gh5833]: https://github.com/encode/django-rest-framework/issues/5833
1918+
[gh5894]: https://github.com/encode/django-rest-framework/issues/5894
1919+
[gh5817]: https://github.com/encode/django-rest-framework/issues/5817
1920+
[gh5815]: https://github.com/encode/django-rest-framework/issues/5815
1921+
[gh5818]: https://github.com/encode/django-rest-framework/issues/5818
1922+
[gh5800]: https://github.com/encode/django-rest-framework/issues/5800
1923+
[gh5676]: https://github.com/encode/django-rest-framework/issues/5676
1924+
[gh5802]: https://github.com/encode/django-rest-framework/issues/5802
1925+
[gh5765]: https://github.com/encode/django-rest-framework/issues/5765
1926+
[gh5764]: https://github.com/encode/django-rest-framework/issues/5764
1927+
[gh5904]: https://github.com/encode/django-rest-framework/issues/5904
1928+
[gh5899]: https://github.com/encode/django-rest-framework/issues/5899

Diff for: rest_framework/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
"""
99

1010
__title__ = 'Django REST framework'
11-
__version__ = '3.7.7'
11+
__version__ = '3.8.0'
1212
__author__ = 'Tom Christie'
1313
__license__ = 'BSD 2-Clause'
14-
__copyright__ = 'Copyright 2011-2017 Tom Christie'
14+
__copyright__ = 'Copyright 2011-2018 Tom Christie'
1515

1616
# Version synonym
1717
VERSION = __version__

Diff for: rest_framework/decorators.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ def handler(self, *args, **kwargs):
7878

7979
if exclude_from_schema:
8080
warnings.warn(
81-
"The `exclude_from_schema` argument to `api_view` is pending deprecation. "
81+
"The `exclude_from_schema` argument to `api_view` is deprecated. "
8282
"Use the `schema` decorator instead, passing `None`.",
83-
PendingDeprecationWarning
83+
DeprecationWarning
8484
)
8585
WrappedAPIView.exclude_from_schema = exclude_from_schema
8686

Diff for: rest_framework/schemas/generators.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,10 @@ def should_include_endpoint(self, path, callback):
208208
return False # Ignore anything except REST framework views.
209209

210210
if hasattr(callback.cls, 'exclude_from_schema'):
211-
fmt = ("The `{}.exclude_from_schema` attribute is pending deprecation. "
211+
fmt = ("The `{}.exclude_from_schema` attribute is deprecated. "
212212
"Set `schema = None` instead.")
213213
msg = fmt.format(callback.cls.__name__)
214-
warnings.warn(msg, PendingDeprecationWarning)
214+
warnings.warn(msg, DeprecationWarning)
215215
if getattr(callback.cls, 'exclude_from_schema', False):
216216
return False
217217

Diff for: tests/test_schemas.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -871,15 +871,15 @@ def test_should_include_endpoint_excludes_correctly(self):
871871
assert should_include == expected
872872

873873
def test_deprecations(self):
874-
with pytest.warns(PendingDeprecationWarning) as record:
874+
with pytest.warns(DeprecationWarning) as record:
875875
@api_view(["GET"], exclude_from_schema=True)
876876
def view(request):
877877
pass
878878

879879
assert len(record) == 1
880880
assert str(record[0].message) == (
881-
"The `exclude_from_schema` argument to `api_view` is pending "
882-
"deprecation. Use the `schema` decorator instead, passing `None`."
881+
"The `exclude_from_schema` argument to `api_view` is deprecated. "
882+
"Use the `schema` decorator instead, passing `None`."
883883
)
884884

885885
class OldFashionedExcludedView(APIView):
@@ -893,13 +893,13 @@ def get(self, request, *args, **kwargs):
893893
]
894894

895895
inspector = EndpointEnumerator(patterns)
896-
with pytest.warns(PendingDeprecationWarning) as record:
896+
with pytest.warns(DeprecationWarning) as record:
897897
inspector.get_api_endpoints()
898898

899899
assert len(record) == 1
900900
assert str(record[0].message) == (
901901
"The `OldFashionedExcludedView.exclude_from_schema` attribute is "
902-
"pending deprecation. Set `schema = None` instead."
902+
"deprecated. Set `schema = None` instead."
903903
)
904904

905905

0 commit comments

Comments
 (0)