Skip to content

Commit a4d91e7

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into develop
2 parents b92b860 + 6c28f1d commit a4d91e7

File tree

10 files changed

+78
-28
lines changed

10 files changed

+78
-28
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ Running the example app
9999

100100
$ git clone https://github.com/django-json-api/django-rest-framework-json-api.git
101101
$ cd django-rest-framework-json-api && pip install -e .
102-
$ django-admin.py runserver
102+
$ django-admin.py runserver --settings=example.settings
103103

104104
Browse to http://localhost:8000
105105

docs/usage.md

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,18 @@
44
The DJA package implements a custom renderer, parser, exception handler, and
55
pagination. To get started enable the pieces in `settings.py` that you want to use.
66

7-
Many features of the JSON:API format standard have been implemented using Mixin classes in `serializers.py`.
8-
The easiest way to make use of those features is to import ModelSerializer variants
7+
Many features of the JSON:API format standard have been implemented using Mixin classes in `serializers.py`.
8+
The easiest way to make use of those features is to import ModelSerializer variants
99
from `rest_framework_json_api` instead of the usual `rest_framework`
1010

1111
### Configuration
12-
We suggest that you simply copy the settings block below and modify it if necessary.
12+
We suggest that you copy the settings block below and modify it if necessary.
1313
``` python
1414
REST_FRAMEWORK = {
15-
'PAGINATE_BY': 10,
16-
'PAGINATE_BY_PARAM': 'page_size',
17-
'MAX_PAGINATE_BY': 100,
18-
# DRF v3.1+
15+
'PAGE_SIZE': 10,
16+
'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler',
1917
'DEFAULT_PAGINATION_CLASS':
2018
'rest_framework_json_api.pagination.PageNumberPagination',
21-
# older than DRF v3.1
22-
'DEFAULT_PAGINATION_SERIALIZER_CLASS':
23-
'rest_framework_json_api.pagination.PaginationSerializer',
2419
'DEFAULT_PARSER_CLASSES': (
2520
'rest_framework_json_api.parsers.JSONParser',
2621
'rest_framework.parsers.FormParser',
@@ -30,12 +25,14 @@ REST_FRAMEWORK = {
3025
'rest_framework_json_api.renderers.JSONRenderer',
3126
'rest_framework.renderers.BrowsableAPIRenderer',
3227
),
28+
'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
3329
}
3430
```
3531

36-
If `PAGINATE_BY` is set the renderer will return a `meta` object with
32+
If `PAGE_SIZE` is set the renderer will return a `meta` object with
3733
record count and a `links` object with the next, previous, first, and last links.
38-
Pages can be selected with the `page` GET parameter.
34+
Pages can be selected with the `page` GET parameter. Page size can be controlled
35+
per request via the `PAGINATE_BY_PARAM` query parameter (`page_size` by default).
3936

4037
### Setting the resource_name
4138

@@ -226,7 +223,7 @@ When set to pluralize:
226223
}
227224
```
228225

229-
Both `JSON_API_PLURALIZE_RELATION_TYPE` and `JSON_API_FORMAT_RELATION_KEYS` can be combined to
226+
Both `JSON_API_PLURALIZE_RELATION_TYPE` and `JSON_API_FORMAT_RELATION_KEYS` can be combined to
230227
achieve different results.
231228

232229
### Meta
@@ -248,7 +245,7 @@ def get_root_meta(self, obj):
248245
```
249246
to the serializer. It must return a dict and will be merged with the existing top level `meta`.
250247

251-
<!--
248+
<!--
252249
### Relationships
253250
### Links
254251
### Included

example/serializers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,5 @@ class CommentSerializer(serializers.ModelSerializer):
7676

7777
class Meta:
7878
model = Comment
79-
fields = ('entry', 'body', 'author',)
79+
exclude = ('created_at', 'modified_at',)
80+
# fields = ('entry', 'body', 'author',)

example/tests/test_serializers.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.core.urlresolvers import reverse
12
from django.test import TestCase
23
from django.utils import timezone
34

@@ -6,6 +7,11 @@
67

78
from example.models import Blog, Entry, Author
89

10+
import pytest
11+
from example.tests.utils import dump_json, redump_json
12+
13+
pytestmark = pytest.mark.django_db
14+
915

1016
class TestResourceIdentifierObjectSerializer(TestCase):
1117
def setUp(self):
@@ -71,3 +77,38 @@ def test_deserialize_many(self):
7177

7278
print(serializer.data)
7379

80+
81+
class TestModelSerializer(object):
82+
def test_model_serializer_with_implicit_fields(self, comment, client):
83+
expected = {
84+
"data": {
85+
"type": "comments",
86+
"id": str(comment.pk),
87+
"attributes": {
88+
"body": comment.body
89+
},
90+
"relationships": {
91+
"entry": {
92+
"data": {
93+
"type": "entries",
94+
"id": str(comment.entry.pk)
95+
}
96+
},
97+
"author": {
98+
"data": {
99+
"type": "authors",
100+
"id": str(comment.author.pk)
101+
}
102+
},
103+
}
104+
}
105+
}
106+
107+
response = client.get(reverse("comment-detail", kwargs={'pk': comment.pk}))
108+
109+
assert response.status_code == 200
110+
111+
actual = redump_json(response.content)
112+
expected_json = dump_json(expected)
113+
114+
assert actual == expected_json

example/tests/test_views.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,22 @@ def test_delete_to_one_relationship_should_fail(self):
145145
response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
146146
assert response.status_code == 405, response.content.decode()
147147

148+
def test_delete_relationship_overriding_with_none(self):
149+
url = '/comments/{}'.format(self.second_comment.id)
150+
request_data = {
151+
'data': {
152+
'type': 'comments',
153+
'relationships': {
154+
'author': {
155+
'data': None
156+
}
157+
}
158+
}
159+
}
160+
response = self.client.patch(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
161+
assert response.status_code == 200, response.content.decode()
162+
assert response.data['author'] == None
163+
148164
def test_delete_to_many_relationship_with_no_change(self):
149165
url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id)
150166
request_data = {

example/urls_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.conf.urls import include, url
22
from rest_framework import routers
33

4-
from example.views import BlogViewSet, EntryViewSet, AuthorViewSet, EntryRelationshipView, BlogRelationshipView, \
4+
from example.views import BlogViewSet, EntryViewSet, AuthorViewSet, CommentViewSet, EntryRelationshipView, BlogRelationshipView, \
55
CommentRelationshipView, AuthorRelationshipView
66
from .api.resources.identity import Identity, GenericIdentity
77

@@ -10,6 +10,7 @@
1010
router.register(r'blogs', BlogViewSet)
1111
router.register(r'entries', EntryViewSet)
1212
router.register(r'authors', AuthorViewSet)
13+
router.register(r'comments', CommentViewSet)
1314

1415
# for the old tests
1516
router.register(r'identities', Identity)

rest_framework_json_api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22

33
__title__ = 'djangorestframework-jsonapi'
4-
__version__ = '2.0.0-alpha.3'
4+
__version__ = '2.0.0-beta.1'
55
__author__ = ''
66
__license__ = 'MIT'
77
__copyright__ = ''

rest_framework_json_api/parsers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def parse_relationships(data):
4040
parsed_relationships = dict()
4141
for field_name, field_data in relationships.items():
4242
field_data = field_data.get('data')
43-
if isinstance(field_data, dict):
43+
if isinstance(field_data, dict) or field_data is None:
4444
parsed_relationships[field_name] = field_data
4545
elif isinstance(field_data, list):
4646
parsed_relationships[field_name] = list(relation for relation in field_data)

rest_framework_json_api/serializers.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,6 @@ class ModelSerializer(IncludedResourcesValidationMixin, SparseFieldsetsMixin, Mo
137137
"""
138138
serializer_related_field = ResourceRelatedField
139139

140-
def __init__(self, *args, **kwargs):
141-
meta_fields = getattr(self.Meta, 'meta_fields', [])
142-
# we add meta_fields to fields so they will be serialized like usual
143-
self.Meta.fields = tuple(tuple(self.Meta.fields) + tuple(meta_fields))
144-
super(ModelSerializer, self).__init__(*args, **kwargs)
145-
146140
def get_field_names(self, declared_fields, info):
147141
"""
148142
We override the parent to omit explicity defined meta fields (such
@@ -155,5 +149,5 @@ def get_field_names(self, declared_fields, info):
155149
field = declared_fields[field_name]
156150
if field_name not in meta_fields:
157151
declared[field_name] = field
158-
return super(ModelSerializer, self).get_field_names(declared, info)
159-
152+
fields = super(ModelSerializer, self).get_field_names(declared, info)
153+
return list(fields) + list(getattr(self.Meta, 'meta_fields', list()))

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def get_package_data(package):
7676
'inflection>=0.3.0'
7777
],
7878
classifiers=[
79-
'Development Status :: 3 - Alpha',
79+
'Development Status :: 4 - Beta',
8080
'Environment :: Web Environment',
8181
'Framework :: Django',
8282
'Intended Audience :: Developers',

0 commit comments

Comments
 (0)