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 9aa259c

Browse files
committed
Merge branch 'develop' of github.com:django-json-api/django-rest-framework-json-api
2 parents 3471569 + cebecf5 commit 9aa259c

File tree

12 files changed

+127
-25
lines changed

12 files changed

+127
-25
lines changed

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ var/
2020
*.egg-info/
2121
.installed.cfg
2222
*.egg
23+
.eggs/
2324

2425
# Installer logs
2526
pip-log.txt

‎.travis.yml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ env:
2626

2727
- DJANGO=">=1.10,<1.11" DRF=">=3.4,<3.5"
2828
before_install:
29-
# Force an upgrade of py to avoid VersionConflict
29+
# Force an upgrade of py & pytest to avoid VersionConflict
3030
- pip install --upgrade py
31+
- pip install "pytest>=2.8,<3"
3132
- pip install codecov
3233
install:
3334
- pip install Django${DJANGO} djangorestframework${DRF}

‎docs/usage.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ class OrderSerializer(serializers.ModelSerializer):
318318

319319
customer = ResourceRelatedField(
320320
queryset=Customer.objects,
321-
related_link_view-name='order-customer-detail',
321+
related_link_view_name='order-customer-detail',
322322
related_link_url_kwarg='order_pk',
323323
self_link_view_name='order-relationships'
324324
)
@@ -399,7 +399,7 @@ The urlconf would need to contain a route like the following:
399399

400400
```python
401401
url(
402-
regex=r'^orders/(?P<pk>[^/.]+/relationships/(?P<related_field>[^/.]+)$',
402+
regex=r'^orders/(?P<pk>[^/.]+)/relationships/(?P<related_field>[^/.]+)$',
403403
view=OrderRelationshipView.as_view(),
404404
name='order-relationships'
405405
)

‎example/tests/test_utils.py‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
Test rest_framework_json_api's utils functions.
3+
"""
4+
from rest_framework_json_api import utils
5+
6+
from ..serializers import EntrySerializer
7+
from ..tests import TestBase
8+
9+
10+
class GetRelatedResourceTests(TestBase):
11+
"""
12+
Ensure the `get_related_resource_type` function returns correct types.
13+
"""
14+
15+
def test_reverse_relation(self):
16+
"""
17+
Ensure reverse foreign keys have their types identified correctly.
18+
"""
19+
serializer = EntrySerializer()
20+
field = serializer.fields['comments']
21+
22+
self.assertEqual(utils.get_related_resource_type(field), 'comments')
23+
24+
def test_m2m_relation(self):
25+
"""
26+
Ensure m2ms have their types identified correctly.
27+
"""
28+
serializer = EntrySerializer()
29+
field = serializer.fields['authors']
30+
31+
self.assertEqual(utils.get_related_resource_type(field), 'authors')

‎example/tests/unit/test_renderers.py‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from example.models import Entry, Comment
2+
from rest_framework_json_api import serializers, views
3+
from rest_framework_json_api.renderers import JSONRenderer
4+
5+
6+
# serializers
7+
class RelatedModelSerializer(serializers.ModelSerializer):
8+
class Meta:
9+
model = Comment
10+
fields = ('id',)
11+
12+
13+
class DummyTestSerializer(serializers.ModelSerializer):
14+
'''
15+
This serializer is a simple compound document serializer which includes only
16+
a single embedded relation
17+
'''
18+
related_models = RelatedModelSerializer(
19+
source='comment_set', many=True, read_only=True)
20+
21+
class Meta:
22+
model = Entry
23+
fields = ('related_models',)
24+
25+
class JSONAPIMeta:
26+
included_resources = ('related_models',)
27+
28+
29+
# views
30+
class DummyTestViewSet(views.ModelViewSet):
31+
queryset = Entry.objects.all()
32+
serializer_class = DummyTestSerializer
33+
34+
35+
def test_simple_reverse_relation_included_renderer():
36+
'''
37+
Test renderer when a single reverse fk relation is passed.
38+
'''
39+
serializer = DummyTestSerializer(instance=Entry())
40+
renderer = JSONRenderer()
41+
rendered = renderer.render(
42+
serializer.data,
43+
renderer_context={'view': DummyTestViewSet()})
44+
45+
assert rendered

‎requirements-development.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-e .
2-
pytest==2.8.2
2+
pytest>=2.9.0,<3.0
33
pytest-django
44
pytest-factoryboy
55
fake-factory

‎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.1.0'
4+
__version__ = '2.1.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
@@ -92,7 +92,7 @@ def parse(self, stream, media_type=None, parser_context=None):
9292
raise ParseError("The resource identifier object must contain an 'id' member")
9393

9494
# Construct the return data
95-
parsed_data = {'id': data.get('id')}
95+
parsed_data = {'id': data.get('id')}if'id'indataelse {}
9696
parsed_data.update(self.parse_attributes(data))
9797
parsed_data.update(self.parse_relationships(data))
9898
parsed_data.update(self.parse_metadata(result))

‎rest_framework_json_api/renderers.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def extract_relationships(fields, resource, resource_instance):
199199
})
200200
continue
201201

202-
if isinstance(field, ListSerializer)andrelation_instanceisnotNone:
202+
if isinstance(field, ListSerializer):
203203
resolved, relation_instance = utils.get_relation_instance(resource_instance, source, field.parent)
204204
if not resolved:
205205
continue

‎rest_framework_json_api/utils.py‎

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22
Utils.
33
"""
44
import copy
5+
import inspect
56
import warnings
67
from collections import OrderedDict
7-
import inspect
88

99
import inflection
10+
from rest_framework import exceptions
11+
from rest_framework.exceptions import APIException
12+
13+
import django
1014
from django.conf import settings
11-
from django.utils import encoding
12-
from django.utils import six
15+
from django.db.models import Manager
16+
from django.utils import encoding, six
1317
from django.utils.module_loading import import_string as import_class_from_dotted_path
1418
from django.utils.translation import ugettext_lazy as _
15-
from django.db.models import Manager
16-
from rest_framework.exceptions import APIException
17-
from rest_framework import exceptions
1819

1920
try:
2021
from rest_framework.serializers import ManyRelatedField
@@ -26,6 +27,14 @@
2627
except ImportError:
2728
HyperlinkedRouterField = type(None)
2829

30+
if django.VERSION >= (1, 9):
31+
from django.db.models.fields.related_descriptors import ManyToManyDescriptor, ReverseManyToOneDescriptor
32+
ReverseManyRelatedObjectsDescriptor = type(None)
33+
else:
34+
from django.db.models.fields.related import ManyRelatedObjectsDescriptor as ManyToManyDescriptor
35+
from django.db.models.fields.related import ForeignRelatedObjectsDescriptor as ReverseManyToOneDescriptor
36+
from django.db.models.fields.related import ReverseManyRelatedObjectsDescriptor
37+
2938

3039
def get_resource_name(context):
3140
"""
@@ -87,6 +96,7 @@ def get_serializer_fields(serializer):
8796
pass
8897
return fields
8998

99+
90100
def format_keys(obj, format_type=None):
91101
"""
92102
Takes either a dict or list and returns it with camelized keys only if
@@ -148,6 +158,7 @@ def format_relation_name(value, format_type=None):
148158
pluralize = getattr(settings, 'JSON_API_PLURALIZE_RELATION_TYPE', None)
149159
return format_resource_type(value, format_type, pluralize)
150160

161+
151162
def format_resource_type(value, format_type=None, pluralize=None):
152163
if format_type is None:
153164
format_type = getattr(settings, 'JSON_API_FORMAT_TYPES', False)
@@ -167,7 +178,6 @@ def get_related_resource_type(relation):
167178
return get_resource_type_from_serializer(relation)
168179
except AttributeError:
169180
pass
170-
171181
relation_model = None
172182
if hasattr(relation, '_meta'):
173183
relation_model = relation._meta.model
@@ -184,7 +194,7 @@ def get_related_resource_type(relation):
184194
elif hasattr(parent_serializer, 'parent') and hasattr(parent_serializer.parent, 'Meta'):
185195
parent_model = getattr(parent_serializer.parent.Meta, 'model', None)
186196

187-
if parent_model is not None:
197+
if parent_model is not None:
188198
if relation.source:
189199
if relation.source != '*':
190200
parent_model_relation = getattr(parent_model, relation.source)
@@ -193,17 +203,17 @@ def get_related_resource_type(relation):
193203
else:
194204
parent_model_relation = getattr(parent_model, parent_serializer.field_name)
195205

196-
if hasattr(parent_model_relation, 'related'):
197-
try:
206+
if type(parent_model_relation) is ReverseManyToOneDescriptor:
207+
if django.VERSION >= (1, 9):
208+
relation_model = parent_model_relation.rel.related_model
209+
elif django.VERSION >= (1, 8):
198210
relation_model = parent_model_relation.related.related_model
199-
except AttributeError:
200-
# Django 1.7
211+
else:
201212
relation_model = parent_model_relation.related.model
202-
elif hasattr(parent_model_relation, 'field'):
203-
try:
204-
relation_model = parent_model_relation.field.remote_field.model
205-
except AttributeError:
206-
relation_model = parent_model_relation.field.related.model
213+
elif type(parent_model_relation) is ManyToManyDescriptor:
214+
relation_model = parent_model_relation.field.remote_field.model
215+
elif type(parent_model_relation) is ReverseManyRelatedObjectsDescriptor:
216+
relation_model = parent_model_relation.field.related.model
207217
else:
208218
return get_related_resource_type(parent_model_relation)
209219

0 commit comments

Comments
(0)

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