Skip to content

Commit 7957fa7

Browse files
committed
Added basic JSON API format. ModelViewSets are mostly working. Issue #32
1 parent 799a760 commit 7957fa7

File tree

8 files changed

+229
-204
lines changed

8 files changed

+229
-204
lines changed

README.rst

Lines changed: 57 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
JSON API and Django Rest Framework
33
====================================
44

5-
.. image:: https://travis-ci.org/django-json-api/rest_framework_json_api.svg?branch=develop
6-
:target: https://travis-ci.org/django-json-api/rest_framework_json_api
5+
.. image:: https://travis-ci.org/django-json-api/rest_framework_ember.svg?branch=develop
6+
:target: https://travis-ci.org/django-json-api/rest_framework_ember
77

88
By default, Django REST Framework will produce a response like::
99

@@ -33,12 +33,14 @@ like the following::
3333
"id": 3,
3434
"attributes": {
3535
"username": "john",
36-
"full_name": "John Coltrane"
37-
},
38-
"meta": {
39-
"count": 20,
40-
},
36+
"full-name": "John Coltrane"
37+
}
4138
}],
39+
"meta": {
40+
"pagination": {
41+
"count": 20
42+
}
43+
}
4244
}
4345

4446

@@ -117,83 +119,83 @@ override ``settings.REST_FRAMEWORK``::
117119
}
118120

119121
If ``PAGINATE_BY`` is set the renderer will return a ``meta`` object with
120-
record count and the next and previous links. Django Rest Framework looks
121-
for the ``page`` GET parameter by default allowing you to make requests for
122-
subsets of the data with ``this.store.find('identity', {page: 2});``.
122+
record count and a ``links`` object with the next and previous links. Pages
123+
can be specified with the ``page`` GET parameter.
123124

124125
resource_name property
125126
^^^^^^^^^^^^^^^^^^^^^^
126127

127-
On resources that do not subclass ``rest_framework.viewsets.ModelViewSet``,
128-
the ``resource_name`` property is required on the class::
128+
You may manually set the ``resource_name`` property on views or serializers to
129+
specify the ``type`` key in the json output. It is automatically set for you as the
130+
plural of the view or model name except on resources that do not subclass
131+
``rest_framework.viewsets.ModelViewSet``::
129132

130133
class Me(generics.GenericAPIView):
131134
"""
132135
Current user's identity endpoint.
133136

134137
GET /me
135138
"""
136-
resource_name = 'data'
139+
resource_name = 'users'
137140
serializer_class = identity_serializers.IdentitySerializer
138141
allowed_methods = ['GET']
139142
permission_classes = (permissions.IsAuthenticated, )
140143

141144

142-
Ember Data <-> Rest Framework Format Conversion
145+
Object Key Formats
143146
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
144-
*(camelization/underscore/pluralize)*
147+
*(dasherize/camelize/underscore/pluralize)*
145148

146-
This package includes the optional ability to automatically convert json requests
147-
and responses from the Ember Data camelCase to python/rest_framework's preferred
148-
underscore. Additionally resource names can be pluralized when an array of objects
149-
are returned. To hook this up include the following in your project settings::
149+
This package includes the ability (off by default) to automatically convert json
150+
requests and responses from the python/rest_framework's preferred underscore to
151+
a format of your choice. To hook this up include the following in your project
152+
settings::
150153

151-
REST_EMBER_FORMAT_KEYS = True
152-
REST_EMBER_PLURALIZE_KEYS = True
154+
JSON_API_FORMAT_KEYS = True
153155

154-
Note: due to the way the inflector works address_1 will convert to address1
155-
on output but cannot convert address1 back to address_1 on POST or PUT. Keep
156+
Note: due to the way the inflector works address_1 can camelize to address1
157+
on output but it cannot convert address1 back to address_1 on POST or PUT. Keep
156158
this in mind when naming fields with numbers in them.
157159

158160

159161
Example - Without format conversion::
160162

161163
{
162-
"identity": [
163-
{
164-
"id": 1,
165-
"username": "john",
166-
"first_name": "John",
167-
"last_name": "Coltrane"
168-
},
169-
{
170-
"id": 2,
171-
"username": "frodo",
172-
"first_name": "Bilbo",
173-
"last_name": "Baggins"
174-
},
175-
],
176-
...
164+
"data": [{
165+
"type": "identities",
166+
"id": 3,
167+
"attributes": {
168+
"username": "john",
169+
"first_name": "John",
170+
"last_name": "Coltrane",
171+
"full_name": "John Coltrane"
172+
},
173+
}],
174+
"meta": {
175+
"pagination": {
176+
"count": 20
177+
}
178+
}
177179
}
178180

179-
Example - With format conversion::
181+
Example - With format conversion set to ``dasherize``::
180182

181183
{
182-
"identities": [
183-
{
184-
"id": 1,
185-
"username": "john",
186-
"firstName": "John",
187-
"lastName": "Coltrane"
188-
},
189-
{
190-
"id": 2,
191-
"username": "frodo",
192-
"firstName": "Bilbo",
193-
"lastName": "Baggins"
194-
},
195-
],
196-
...
184+
"data": [{
185+
"type": "identities",
186+
"id": 3,
187+
"attributes": {
188+
"username": "john",
189+
"first-name": "John",
190+
"last-name": "Coltrane",
191+
"full-name": "John Coltrane"
192+
},
193+
}],
194+
"meta": {
195+
"pagination": {
196+
"count": 20
197+
}
198+
}
197199
}
198200

199201

@@ -289,7 +291,7 @@ For example::
289291

290292

291293
Set the ``resource_name`` property on the object to ``False``, and the data
292-
will be returned as it is above.
294+
will be returned without modification.
293295

294296

295297
------
@@ -303,4 +305,3 @@ rest_framework_json_api.mixins.MultipleIDMixin
303305
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
304306

305307
Overrides ``get_queryset`` to filter by ``ids[]`` in URL query params.
306-

example/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
MIDDLEWARE_CLASSES = ()
3535

36+
JSON_API_FORMAT_KEYS = 'dasherize'
3637
REST_FRAMEWORK = {
3738
'PAGINATE_BY': 1,
3839
'PAGINATE_BY_PARAM': 'page_size',

example/tests/test_format_keys.py

Lines changed: 12 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@ def setUp(self):
1818
self.detail_url = reverse('user-detail', kwargs={'pk': self.miles.pk})
1919

2020
# Set the format keys settings.
21-
setattr(settings, 'REST_EMBER_FORMAT_KEYS', True)
22-
setattr(settings, 'REST_EMBER_PLURALIZE_KEYS', True)
21+
setattr(settings, 'JSON_API_FORMAT_KEYS', True)
2322

2423
def tearDown(self):
2524
# Remove the format keys settings.
26-
delattr(settings, 'REST_EMBER_FORMAT_KEYS')
27-
delattr(settings, 'REST_EMBER_PLURALIZE_KEYS')
25+
delattr(settings, 'JSON_API_FORMAT_KEYS')
2826

2927

3028
def test_camelization(self):
@@ -36,52 +34,20 @@ def test_camelization(self):
3634

3735
user = get_user_model().objects.all()[0]
3836
expected = {
39-
u'users': [{
37+
u'data': {
38+
u'type': u'users',
4039
u'id': user.pk,
41-
u'firstName': user.first_name,
42-
u'lastName': user.last_name,
43-
u'email': user.email
44-
}]
40+
u'attributes': {
41+
u'firstName': user.first_name,
42+
u'lastName': user.last_name,
43+
u'email': user.email
44+
},
45+
}
4546
}
4647

4748
json_content = json.loads(response.content.decode('utf8'))
48-
meta = json_content.get('meta')
49+
links = json_content.get('links')
4950

5051
self.assertEquals(expected.get('users'), json_content.get('users'))
5152
self.assertEqual(u'http://testserver/identities?page=2',
52-
meta.get('nextLink'))
53-
54-
def test_pluralization(self):
55-
"""
56-
Test that the key name is pluralized.
57-
"""
58-
response = self.client.get(self.list_url, {'page_size': 2})
59-
self.assertEqual(response.status_code, 200)
60-
61-
users = get_user_model().objects.all()
62-
expected = {
63-
u'users': [{
64-
u'id': users[0].pk,
65-
u'firstName': users[0].first_name,
66-
u'lastName': users[0].last_name,
67-
u'email': users[0].email
68-
},{
69-
u'id': users[1].pk,
70-
u'firstName': users[1].first_name,
71-
u'lastName': users[1].last_name,
72-
u'email': users[1].email
73-
}]
74-
}
75-
76-
json_content = json.loads(response.content.decode('utf8'))
77-
self.assertEquals(expected.get('users'), json_content.get('users'))
78-
79-
def test_empty_pluralization(self):
80-
#test that the key is still pluralized when there are no records for the
81-
#model, as long as the endpoint serves a list
82-
response = self.client.get(reverse('user-empty-list'))
83-
self.assertEqual(response.status_code, 200)
84-
85-
json_content = json.loads(response.content.decode('utf8'))
86-
self.assertEqual(json_content.get('users'), [])
87-
53+
links.get('next'))

0 commit comments

Comments
 (0)