Skip to content

Commit a8bdf10

Browse files
author
Oliver Sauder
committed
Preserve values from being formatted
Introduce `JSON_API_FORMAT_FIELD_NAMES` which preserves keys of values. `JSON_API_FORMAT_KEYS` still exists but is deprecated.
1 parent 028f191 commit a8bdf10

File tree

13 files changed

+133
-28
lines changed

13 files changed

+133
-28
lines changed

example/api/resources/identity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def posts(self, request):
3737
encoding.force_text('identities'): IdentitySerializer(identities, many=True).data,
3838
encoding.force_text('posts'): PostSerializer(posts, many=True).data,
3939
}
40-
return Response(utils.format_keys(data, format_type='camelize'))
40+
return Response(utils.format_field_names(data, format_type='camelize'))
4141

4242
@detail_route()
4343
def manual_resource_name(self, request, *args, **kwargs):

example/settings/dev.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565

6666
INTERNAL_IPS = ('127.0.0.1', )
6767

68-
JSON_API_FORMAT_KEYS = 'camelize'
68+
JSON_API_FORMAT_FIELD_NAMES = 'camelize'
6969
JSON_API_FORMAT_TYPES = 'camelize'
7070
REST_FRAMEWORK = {
7171
'PAGE_SIZE': 5,

example/settings/test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
ROOT_URLCONF = 'example.urls_test'
1111

12-
JSON_API_FORMAT_KEYS = 'camelize'
12+
JSON_API_FIELD_NAMES = 'camelize'
1313
JSON_API_FORMAT_TYPES = 'camelize'
1414
JSON_API_PLURALIZE_TYPES = True
1515
REST_FRAMEWORK.update({

example/tests/test_generic_viewset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from example.tests import TestBase
55

66

7-
@override_settings(JSON_API_FORMAT_KEYS='dasherize')
7+
@override_settings(JSON_API_FORMAT_FIELD_NAMES='dasherize')
88
class GenericViewSet(TestBase):
99
"""
1010
Test expected responses coming from a Generic ViewSet

example/tests/test_model_viewsets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from example.tests import TestBase
88

99

10-
@override_settings(JSON_API_FORMAT_KEYS='dasherize')
10+
@override_settings(JSON_API_FORMAT_FIELD_NAMES='dasherize')
1111
class ModelViewSetTests(TestBase):
1212
"""
1313
Test usage with ModelViewSets, also tests pluralization, camelization,

example/tests/test_parsers.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import json
22
from io import BytesIO
33

4-
from django.test import TestCase
4+
from django.test import TestCase, override_settings
55
from rest_framework.exceptions import ParseError
66

77
from rest_framework_json_api.parsers import JSONParser
@@ -22,7 +22,10 @@ def __init__(self):
2222
data = {
2323
'data': {
2424
'id': 123,
25-
'type': 'Blog'
25+
'type': 'Blog',
26+
'attributes': {
27+
'json-value': {'JsonKey': 'JsonValue'}
28+
},
2629
},
2730
'meta': {
2831
'random_key': 'random_value'
@@ -31,13 +34,25 @@ def __init__(self):
3134

3235
self.string = json.dumps(data)
3336

34-
def test_parse_include_metadata(self):
37+
@override_settings(JSON_API_FORMAT_KEYS='camelize')
38+
def test_parse_include_metadata_format_keys(self):
3539
parser = JSONParser()
3640

3741
stream = BytesIO(self.string.encode('utf-8'))
3842
data = parser.parse(stream, None, self.parser_context)
3943

4044
self.assertEqual(data['_meta'], {'random_key': 'random_value'})
45+
self.assertEqual(data['json_value'], {'json_key': 'JsonValue'})
46+
47+
@override_settings(JSON_API_FORMAT_FIELD_NAMES='dasherize')
48+
def test_parse_include_metadata_format_field_names(self):
49+
parser = JSONParser()
50+
51+
stream = BytesIO(self.string.encode('utf-8'))
52+
data = parser.parse(stream, None, self.parser_context)
53+
54+
self.assertEqual(data['_meta'], {'random_key': 'random_value'})
55+
self.assertEqual(data['json_value'], {'JsonKey': 'JsonValue'})
4156

4257
def test_parse_invalid_data(self):
4358
parser = JSONParser()

example/tests/unit/test_renderers.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import json
2+
13
from rest_framework_json_api import serializers, views
24
from rest_framework_json_api.renderers import JSONRenderer
35

@@ -19,9 +21,14 @@ class DummyTestSerializer(serializers.ModelSerializer):
1921
related_models = RelatedModelSerializer(
2022
source='comments', many=True, read_only=True)
2123

24+
json_field = serializers.SerializerMethodField()
25+
26+
def get_json_field(self, entry):
27+
return {'JsonKey': 'JsonValue'}
28+
2229
class Meta:
2330
model = Entry
24-
fields = ('related_models',)
31+
fields = ('related_models', 'json_field')
2532

2633
class JSONAPIMeta:
2734
included_resources = ('related_models',)
@@ -61,3 +68,22 @@ def test_simple_reverse_relation_included_read_only_viewset():
6168
ReadOnlyDummyTestViewSet)
6269

6370
assert rendered
71+
72+
73+
def test_render_format_field_names(settings):
74+
"""Test that json field is kept untouched."""
75+
settings.JSON_API_FORMAT_FIELD_NAMES = 'dasherize'
76+
rendered = render_dummy_test_serialized_view(DummyTestViewSet)
77+
78+
result = json.loads(rendered.decode())
79+
assert result['data']['attributes']['json-field'] == {'JsonKey': 'JsonValue'}
80+
81+
82+
def test_render_format_keys(settings):
83+
"""Test that json field value keys are formated."""
84+
delattr(settings, 'JSON_API_FORMAT_FILED_NAMES')
85+
settings.JSON_API_FORMAT_KEYS = 'dasherize'
86+
rendered = render_dummy_test_serialized_view(DummyTestViewSet)
87+
88+
result = json.loads(rendered.decode())
89+
assert result['data']['attributes']['json-field'] == {'json-key': 'JsonValue'}

example/tests/unit/test_settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ def test_settings_default():
1313

1414

1515
def test_settings_override(settings):
16-
settings.JSON_API_FORMAT_KEYS = 'dasherize'
17-
assert json_api_settings.FORMAT_KEYS == 'dasherize'
16+
settings.JSON_API_FORMAT_FIELD_NAMES = 'dasherize'
17+
assert json_api_settings.FORMAT_FIELD_NAMES == 'dasherize'

example/tests/unit/test_utils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,19 @@ def test_format_keys():
8484
assert utils.format_keys([underscored], 'dasherize') == output
8585

8686

87+
@pytest.mark.parametrize("format_type,output", [
88+
('camelize', {'fullName': {'last-name': 'a', 'first-name': 'b'}}),
89+
('capitalize', {'FullName': {'last-name': 'a', 'first-name': 'b'}}),
90+
('dasherize', {'full-name': {'last-name': 'a', 'first-name': 'b'}}),
91+
('underscore', {'full_name': {'last-name': 'a', 'first-name': 'b'}}),
92+
])
93+
def test_format_field_names(settings, format_type, output):
94+
settings.JSON_API_FORMAT_FIELD_NAMES = format_type
95+
96+
value = {'full_name': {'last-name': 'a', 'first-name': 'b'}}
97+
assert utils.format_field_names(value, format_type) == output
98+
99+
87100
def test_format_value():
88101
assert utils.format_value('first_name', 'camelize') == 'firstName'
89102
assert utils.format_value('first_name', 'capitalize') == 'FirstName'

rest_framework_json_api/parsers.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,26 @@ class JSONParser(parsers.JSONParser):
3232
@staticmethod
3333
def parse_attributes(data):
3434
attributes = data.get('attributes')
35-
uses_format_translation = json_api_settings.FORMAT_KEYS
35+
uses_format_translation = json_api_settings.format_type
3636

3737
if not attributes:
3838
return dict()
3939
elif uses_format_translation:
4040
# convert back to python/rest_framework's preferred underscore format
41-
return utils.format_keys(attributes, 'underscore')
41+
return utils._format_object(attributes, 'underscore')
4242
else:
4343
return attributes
4444

4545
@staticmethod
4646
def parse_relationships(data):
47-
uses_format_translation = json_api_settings.FORMAT_KEYS
47+
uses_format_translation = json_api_settings.format_type
4848
relationships = data.get('relationships')
4949

5050
if not relationships:
5151
relationships = dict()
5252
elif uses_format_translation:
5353
# convert back to python/rest_framework's preferred underscore format
54-
relationships = utils.format_keys(relationships, 'underscore')
54+
relationships = utils._format_object(relationships, 'underscore')
5555

5656
# Parse the relationships
5757
parsed_relationships = dict()

0 commit comments

Comments
 (0)