Skip to content

support nested structures #776

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
May 14, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Note that in line with [Django REST Framework policy](http://www.django-rest-framework.org/topics/release-notes/),
any parts of the framework not mentioned in the documentation should generally be considered private API, and may be subject to change.

## [3.2.0] - pending

### Added

* Added support for serializiing complex structures as attributes. For details please reffer to #769

## [3.1.0] - 2020-02-08

### Added
Expand Down
17 changes: 17 additions & 0 deletions example/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,23 @@ def get_first_entry(self, obj):
return obj.entries.first()


class CommentWithNestedFieldsSerializer(serializers.ModelSerializer):
entry = EntryDRFSerializers()

class Meta:
model = Comment
exclude = ('created_at', 'modified_at', 'author')
# fields = ('entry', 'body', 'author',)


class AuthorWithNestedFieldsSerializer(serializers.ModelSerializer):
comments = CommentWithNestedFieldsSerializer(many=True)

class Meta:
model = Author
fields = ('name', 'email', 'comments')


class WriterSerializer(serializers.ModelSerializer):
included_serializers = {
'bio': AuthorBioSerializer
Expand Down
93 changes: 93 additions & 0 deletions example/tests/test_rendering_strategies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from __future__ import absolute_import

import pytest
from django.utils import timezone
from rest_framework.reverse import reverse

from rest_framework_json_api.settings import JSONAPISettings
from . import TestBase
from example.models import Author, Blog, Comment, Entry
from django.test import override_settings


class TestRenderingStrategy(TestBase):
list_url = reverse('authors-nested-list')

def setUp(self):
super(TestRenderingStrategy, self).setUp()
self.blog = Blog.objects.create(name='Some Blog', tagline="It's a blog")
self.entry = Entry.objects.create(
blog=self.blog,
headline='headline',
body_text='body_text',
pub_date=timezone.now(),
mod_date=timezone.now(),
n_comments=0,
n_pingbacks=0,
rating=3
)
for i in range(1, 6):
name = 'some_author{}'.format(i)
self.entry.authors.add(
Author.objects.create(name=name, email='{}@example.org'.format(name))
)

self.comment = Comment.objects.create(
entry=self.entry,
body='testing one two three',
author=Author.objects.first()
)

def test_attribute_rendering_strategy(self):
with override_settings(JSON_API_NESTED_SERIALIZERS_RENDERING_STRATEGY='ATTRIBUTE'):
response = self.client.get(self.list_url)

expected = {
"links": {
"first": "http://testserver/authors-nested?page%5Bnumber%5D=1",
"last": "http://testserver/authors-nested?page%5Bnumber%5D=5",
"next": "http://testserver/authors-nested?page%5Bnumber%5D=2",
"prev": None
},
"data": [
{
"type": "authors",
"id": "1",
"attributes": {
"name": "some_author1",
"email": "[email protected]",
"comments": [
{
"id": 1,
"entry": {
"tags": [],
"url": "http://testserver/drf-blogs/1"
},
"body": "testing one two three"
}
]
}
}
],
"meta": {
"pagination": {
"page": 1,
"pages": 5,
"count": 5
}
}
}
assert expected == response.json()


class TestRenderingStrategySettings(TestBase):

def test_deprecation(self):
with pytest.deprecated_call():
JSONAPISettings()

def test_invalid_strategy(self):
class Settings:
JSON_API_NESTED_SERIALIZERS_RENDERING_STRATEGY = 'SOME_INVALID_STRATEGY'
with pytest.raises(AttributeError):
JSONAPISettings(user_settings=Settings())
4 changes: 3 additions & 1 deletion example/urls_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
NoFiltersetEntryViewSet,
NonPaginatedEntryViewSet,
ProjectTypeViewset,
ProjectViewset
ProjectViewset,
AuthorWithNestedFieldsViewSet
)

router = routers.DefaultRouter(trailing_slash=False)
Expand All @@ -32,6 +33,7 @@
router.register(r'filterset-entries', FiltersetEntryViewSet, 'filterset-entry')
router.register(r'nofilterset-entries', NoFiltersetEntryViewSet, 'nofilterset-entry')
router.register(r'authors', AuthorViewSet)
router.register(r'authors-nested', AuthorWithNestedFieldsViewSet, 'authors-nested')
router.register(r'comments', CommentViewSet)
router.register(r'companies', CompanyViewset)
router.register(r'projects', ProjectViewset)
Expand Down
9 changes: 7 additions & 2 deletions example/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
EntryDRFSerializers,
EntrySerializer,
ProjectSerializer,
ProjectTypeSerializer
)
ProjectTypeSerializer,
AuthorWithNestedFieldsSerializer)

HTTP_422_UNPROCESSABLE_ENTITY = 422

Expand Down Expand Up @@ -175,6 +175,11 @@ class AuthorViewSet(ModelViewSet):
serializer_class = AuthorSerializer


class AuthorWithNestedFieldsViewSet(ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorWithNestedFieldsSerializer


class CommentViewSet(ModelViewSet):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
Expand Down
4 changes: 2 additions & 2 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[pytest]
DJANGO_SETTINGS_MODULE=example.settings.test
filterwarnings =
error::DeprecationWarning
error::PendingDeprecationWarning
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
Loading