Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ab3fbfc

Browse files
authored
Remove obsolete code for upcoming major release (#837)
* Deleted outdated `source` attribute of `SerializerMethodField` * Deleted outdated strategy to render serializer as relationship
1 parent 67cf789 commit ab3fbfc

File tree

10 files changed

+33
-217
lines changed

10 files changed

+33
-217
lines changed

‎CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ any parts of the framework not mentioned in the documentation should generally b
1010

1111
## [Unreleased]
1212

13+
This release is not backwards compatible. For easy migration best upgrade first to version
14+
3.2.0 and resolve all deprecation warnings before updating to 4.0.0
15+
1316
### Added
1417

1518
* Added support for Django REST framework 3.12
@@ -20,6 +23,8 @@ any parts of the framework not mentioned in the documentation should generally b
2023
* Removed support for Django 1.11.
2124
* Removed support for Django 2.1.
2225
* Removed support for Django REST framework 3.10, 3.11
26+
* Removed obsolete `source` argument of `SerializerMethodResourceRelatedField`
27+
* Removed obsolete setting `JSON_API_SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE` to render nested serializers as relationships. Default is as attribute now.
2328

2429

2530
## [3.2.0] - 2020年08月26日

‎example/settings/dev.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767

6868
JSON_API_FORMAT_FIELD_NAMES = 'camelize'
6969
JSON_API_FORMAT_TYPES = 'camelize'
70-
JSON_API_SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE = True
7170
REST_FRAMEWORK = {
7271
'PAGE_SIZE': 5,
7372
'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler',

‎example/tests/snapshots/snap_test_errors.py‎

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,16 @@
3232
]
3333
}
3434

35-
snapshots['test_second_level_array_error 1'] = {
35+
snapshots['test_many_third_level_dict_errors 1'] = {
3636
'errors': [
37+
{
38+
'code': 'required',
39+
'detail': 'This field is required.',
40+
'source': {
41+
'pointer': '/data/attributes/comments/0/attachment/data'
42+
},
43+
'status': '400'
44+
},
3745
{
3846
'code': 'required',
3947
'detail': 'This field is required.',
@@ -45,37 +53,37 @@
4553
]
4654
}
4755

48-
snapshots['test_second_level_dict_error 1'] = {
56+
snapshots['test_second_level_array_error 1'] = {
4957
'errors': [
5058
{
5159
'code': 'required',
5260
'detail': 'This field is required.',
5361
'source': {
54-
'pointer': '/data/attributes/comment/body'
62+
'pointer': '/data/attributes/comments/0/body'
5563
},
5664
'status': '400'
5765
}
5866
]
5967
}
6068

61-
snapshots['test_third_level_array_error 1'] = {
69+
snapshots['test_second_level_dict_error 1'] = {
6270
'errors': [
6371
{
6472
'code': 'required',
6573
'detail': 'This field is required.',
6674
'source': {
67-
'pointer': '/data/attributes/comments/0/attachments/0/data'
75+
'pointer': '/data/attributes/comment/body'
6876
},
6977
'status': '400'
7078
}
7179
]
7280
}
7381

74-
snapshots['test_third_level_custom_array_error 1'] = {
82+
snapshots['test_third_level_array_error 1'] = {
7583
'errors': [
7684
{
77-
'code': 'invalid',
78-
'detail': 'Too short data',
85+
'code': 'required',
86+
'detail': 'This field is required.',
7987
'source': {
8088
'pointer': '/data/attributes/comments/0/attachments/0/data'
8189
},
@@ -84,20 +92,20 @@
8492
]
8593
}
8694

87-
snapshots['test_third_level_dict_error 1'] = {
95+
snapshots['test_third_level_custom_array_error 1'] = {
8896
'errors': [
8997
{
90-
'code': 'required',
91-
'detail': 'This field is required.',
98+
'code': 'invalid',
99+
'detail': 'Too short data',
92100
'source': {
93-
'pointer': '/data/attributes/comments/0/attachment/data'
101+
'pointer': '/data/attributes/comments/0/attachments/0/data'
94102
},
95103
'status': '400'
96104
}
97105
]
98106
}
99107

100-
snapshots['test_many_third_level_dict_errors 1'] = {
108+
snapshots['test_third_level_dict_error 1'] = {
101109
'errors': [
102110
{
103111
'code': 'required',
@@ -106,16 +114,6 @@
106114
'pointer': '/data/attributes/comments/0/attachment/data'
107115
},
108116
'status': '400'
109-
},
110-
{
111-
'code': 'required',
112-
'detail': 'This field is required.',
113-
'source': {
114-
'pointer': '/data/attributes/comments/0/body'
115-
},
116-
'status': '400'
117117
}
118118
]
119119
}
120-
121-
snapshots['test_deprecation_warning 1'] = 'Rendering nested serializer as relationship is deprecated. Use `ResourceRelatedField` instead if DummyNestedSerializer in serializer example.tests.test_errors.test_deprecation_warning.<locals>.DummySerializer should remain a relationship. Otherwise set JSON_API_SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE to True to render nested serializer as nested json attribute'

‎example/tests/test_errors.py‎

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ def some_blog(db):
6262

6363
def perform_error_test(client, data):
6464
with override_settings(
65-
JSON_API_SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE=True,
6665
ROOT_URLCONF=__name__
6766
):
6867
url = reverse('entries-nested-list')
@@ -222,18 +221,3 @@ def test_many_third_level_dict_errors(client, some_blog, snapshot):
222221
}
223222

224223
snapshot.assert_match(perform_error_test(client, data))
225-
226-
227-
@pytest.mark.filterwarnings('default::DeprecationWarning:rest_framework_json_api.serializers')
228-
def test_deprecation_warning(recwarn, settings, snapshot):
229-
settings.JSON_API_SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE = False
230-
231-
class DummyNestedSerializer(serializers.Serializer):
232-
field = serializers.CharField()
233-
234-
class DummySerializer(serializers.Serializer):
235-
nested = DummyNestedSerializer(many=True)
236-
237-
assert len(recwarn) == 1
238-
warning = recwarn.pop(DeprecationWarning)
239-
snapshot.assert_match(str(warning.message))

‎example/tests/unit/test_renderers.py‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import json
22

33
import pytest
4-
from django.test import override_settings
54
from django.utils import timezone
65

76
from rest_framework_json_api import serializers, views
@@ -173,7 +172,7 @@ def test_extract_relation_instance(comment):
173172
assert got == comment.entry.blog
174173

175174

176-
def test_attribute_rendering_strategy(db):
175+
def test_render_serializer_as_attribute(db):
177176
# setting up
178177
blog = Blog.objects.create(name='Some Blog', tagline="It's a blog")
179178
entry = Entry.objects.create(
@@ -196,10 +195,8 @@ def test_attribute_rendering_strategy(db):
196195
author=Author.objects.first()
197196
)
198197

199-
with override_settings(
200-
JSON_API_SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE=True):
201-
rendered = render_dummy_test_serialized_view(AuthorWithNestedFieldsViewSet, author)
202-
result = json.loads(rendered.decode())
198+
rendered = render_dummy_test_serialized_view(AuthorWithNestedFieldsViewSet, author)
199+
result = json.loads(rendered.decode())
203200

204201
expected = {
205202
"data": {

‎example/tests/unit/test_serializer_method_field.py‎

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import absolute_import
22

3-
import pytest
43
from rest_framework import serializers
54

65
from rest_framework_json_api.relations import SerializerMethodResourceRelatedField
@@ -39,28 +38,3 @@ def get_custom_entry(self, instance):
3938

4039
serializer = BlogSerializer(instance=Blog())
4140
assert serializer.data['one_entry']['id'] == '100'
42-
43-
44-
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
45-
def test_source():
46-
class BlogSerializer(serializers.ModelSerializer):
47-
one_entry = SerializerMethodResourceRelatedField(
48-
model=Entry,
49-
source='get_custom_entry'
50-
)
51-
52-
class Meta:
53-
model = Blog
54-
fields = ['one_entry']
55-
56-
def get_custom_entry(self, instance):
57-
return Entry(id=100)
58-
59-
serializer = BlogSerializer(instance=Blog())
60-
assert serializer.data['one_entry']['id'] == '100'
61-
62-
63-
@pytest.mark.filterwarnings("error::DeprecationWarning")
64-
def test_source_is_deprecated():
65-
with pytest.raises(DeprecationWarning):
66-
SerializerMethodResourceRelatedField(model=Entry, source='get_custom_entry')

‎rest_framework_json_api/relations.py‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import json
2-
import warnings
32
from collections import OrderedDict
43

54
import inflection
@@ -349,11 +348,6 @@ def to_internal_value(self, data):
349348

350349
class SerializerMethodFieldBase(Field):
351350
def __init__(self, method_name=None, **kwargs):
352-
if not method_name and kwargs.get('source'):
353-
method_name = kwargs.pop('source')
354-
warnings.warn(DeprecationWarning(
355-
"'source' argument of {cls} is deprecated, use 'method_name' "
356-
"as in SerializerMethodField".format(cls=self.__class__.__name__)), stacklevel=3)
357351
self.method_name = method_name
358352
kwargs['source'] = '*'
359353
kwargs['read_only'] = True

‎rest_framework_json_api/renderers.py‎

Lines changed: 3 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,12 @@
1111
from rest_framework import relations, renderers
1212
from rest_framework.fields import SkipField, get_attribute
1313
from rest_framework.relations import PKOnlyObject
14-
from rest_framework.serializers import BaseSerializer, ListSerializer, Serializer
14+
from rest_framework.serializers import ListSerializer, Serializer
1515
from rest_framework.settings import api_settings
1616

1717
import rest_framework_json_api
1818
from rest_framework_json_api import utils
1919
from rest_framework_json_api.relations import HyperlinkedMixin, ResourceRelatedField, SkipDataMixin
20-
from rest_framework_json_api.settings import json_api_settings
2120

2221

2322
class JSONRenderer(renderers.JSONRenderer):
@@ -53,7 +52,6 @@ def extract_attributes(cls, fields, resource):
5352
Builds the `attributes` object of the JSON API resource object.
5453
"""
5554
data = OrderedDict()
56-
render_nested_as_attribute = json_api_settings.SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE
5755
for field_name, field in iter(fields.items()):
5856
# ID is always provided in the root of JSON API so remove it from attributes
5957
if field_name == 'id':
@@ -67,9 +65,6 @@ def extract_attributes(cls, fields, resource):
6765
):
6866
continue
6967

70-
if isinstance(field, BaseSerializer) and not render_nested_as_attribute:
71-
continue
72-
7368
# Skip read_only attribute fields when `resource` is an empty
7469
# serializer. Prevents the "Raw Data" form of the browsable API
7570
# from rendering `"foo": null` for read only fields
@@ -94,7 +89,6 @@ def extract_relationships(cls, fields, resource, resource_instance):
9489
from rest_framework_json_api.relations import ResourceRelatedField
9590

9691
data = OrderedDict()
97-
render_nested_as_attribute = json_api_settings.SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE
9892

9993
# Don't try to extract relationships from a non-existent resource
10094
if resource_instance is None:
@@ -111,13 +105,10 @@ def extract_relationships(cls, fields, resource, resource_instance):
111105

112106
# Skip fields without relations
113107
if not isinstance(
114-
field, (relations.RelatedField, relations.ManyRelatedField, BaseSerializer)
108+
field, (relations.RelatedField, relations.ManyRelatedField)
115109
):
116110
continue
117111

118-
if isinstance(field, BaseSerializer) and render_nested_as_attribute:
119-
continue
120-
121112
source = field.source
122113
relation_type = utils.get_related_resource_type(field)
123114

@@ -252,56 +243,6 @@ def extract_relationships(cls, fields, resource, resource_instance):
252243
})
253244
continue
254245

255-
if isinstance(field, ListSerializer):
256-
resolved, relation_instance = utils.get_relation_instance(
257-
resource_instance, source, field.parent
258-
)
259-
if not resolved:
260-
continue
261-
262-
relation_data = list()
263-
264-
serializer_data = resource.get(field_name)
265-
resource_instance_queryset = list(relation_instance)
266-
if isinstance(serializer_data, list):
267-
for position in range(len(serializer_data)):
268-
nested_resource_instance = resource_instance_queryset[position]
269-
nested_resource_instance_type = (
270-
relation_type or
271-
utils.get_resource_type_from_instance(nested_resource_instance)
272-
)
273-
274-
relation_data.append(OrderedDict([
275-
('type', nested_resource_instance_type),
276-
('id', encoding.force_str(nested_resource_instance.pk))
277-
]))
278-
279-
data.update({field_name: {'data': relation_data}})
280-
continue
281-
282-
if isinstance(field, Serializer):
283-
relation_instance_id = getattr(resource_instance, source + "_id", None)
284-
if not relation_instance_id:
285-
resolved, relation_instance = utils.get_relation_instance(
286-
resource_instance, source, field.parent
287-
)
288-
if not resolved:
289-
continue
290-
291-
if relation_instance is not None:
292-
relation_instance_id = relation_instance.pk
293-
294-
data.update({
295-
field_name: {
296-
'data': (
297-
OrderedDict([
298-
('type', relation_type),
299-
('id', encoding.force_str(relation_instance_id))
300-
]) if resource.get(field_name) else None)
301-
}
302-
})
303-
continue
304-
305246
return utils.format_field_names(data)
306247

307248
@classmethod
@@ -336,7 +277,6 @@ def extract_included(cls, fields, resource, resource_instance, included_resource
336277
included_serializers = utils.get_included_serializers(current_serializer)
337278
included_resources = copy.copy(included_resources)
338279
included_resources = [inflection.underscore(value) for value in included_resources]
339-
render_nested_as_attribute = json_api_settings.SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE
340280

341281
for field_name, field in iter(fields.items()):
342282
# Skip URL field
@@ -345,13 +285,10 @@ def extract_included(cls, fields, resource, resource_instance, included_resource
345285

346286
# Skip fields without relations
347287
if not isinstance(
348-
field, (relations.RelatedField, relations.ManyRelatedField, BaseSerializer)
288+
field, (relations.RelatedField, relations.ManyRelatedField)
349289
):
350290
continue
351291

352-
if isinstance(field, BaseSerializer) and render_nested_as_attribute:
353-
continue
354-
355292
try:
356293
included_resources.remove(field_name)
357294
except ValueError:

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /