Skip to content

Commit d5e1227

Browse files
committed
Merge pull request #172 from lukaslundgren/develop
Included field might not be set
2 parents ce945f2 + 58909d0 commit d5e1227

File tree

6 files changed

+48
-4
lines changed

6 files changed

+48
-4
lines changed

example/factories/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import factory
55
from faker import Factory as FakerFactory
6-
from example.models import Blog, Author, Entry, Comment
6+
from example.models import Blog, Author, AuthorBio, Entry, Comment
77

88
faker = FakerFactory.create()
99
faker.seed(983843)
@@ -23,6 +23,14 @@ class Meta:
2323
email = factory.LazyAttribute(lambda x: faker.email())
2424

2525

26+
class AuthorBioFactory(factory.django.DjangoModelFactory):
27+
class Meta:
28+
model = AuthorBio
29+
30+
author = factory.SubFactory(AuthorFactory)
31+
body = factory.LazyAttribute(lambda x: faker.text())
32+
33+
2634
class EntryFactory(factory.django.DjangoModelFactory):
2735
class Meta:
2836
model = Entry

example/models.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ def __str__(self):
3434
return self.name
3535

3636

37+
@python_2_unicode_compatible
38+
class AuthorBio(BaseModel):
39+
author = models.OneToOneField(Author, related_name='bio')
40+
body = models.TextField()
41+
42+
def __str__(self):
43+
return self.author.name
44+
45+
3746
@python_2_unicode_compatible
3847
class Entry(BaseModel):
3948
blog = models.ForeignKey(Blog)

example/serializers.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from rest_framework_json_api import serializers, relations
2-
from example.models import Blog, Entry, Author, Comment
2+
from example.models import Blog, Entry, Author, AuthorBio, Comment
33

44

55
class BlogSerializer(serializers.ModelSerializer):
@@ -38,11 +38,21 @@ class Meta:
3838
'authors', 'comments', 'suggested',)
3939

4040

41+
class AuthorBioSerializer(serializers.ModelSerializer):
42+
43+
class Meta:
44+
model = AuthorBio
45+
fields = ('author', 'body',)
46+
47+
4148
class AuthorSerializer(serializers.ModelSerializer):
49+
included_serializers = {
50+
'bio': AuthorBioSerializer
51+
}
4252

4353
class Meta:
4454
model = Author
45-
fields = ('name', 'email',)
55+
fields = ('name', 'email', 'bio')
4656

4757

4858
class CommentSerializer(serializers.ModelSerializer):

example/tests/conftest.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import pytest
22
from pytest_factoryboy import register
33

4-
from example.factories import BlogFactory, AuthorFactory, EntryFactory, CommentFactory
4+
from example.factories import BlogFactory, AuthorFactory, AuthorBioFactory, EntryFactory, CommentFactory
55

66
register(BlogFactory)
77
register(AuthorFactory)
8+
register(AuthorBioFactory)
89
register(EntryFactory)
910
register(CommentFactory)
1011

example/tests/integration/test_includes.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,17 @@ def test_dynamic_related_data_is_included(single_entry, entry_factory, client):
3636
assert [x.get('type') for x in included] == ['entries'], 'Dynamic included types are incorrect'
3737
assert len(included) == 1, 'The dynamically included blog entries are of an incorrect count'
3838

39+
40+
def test_missing_field_not_included(author_bio_factory, author_factory, client):
41+
# First author does not have a bio
42+
author = author_factory()
43+
response = client.get(reverse('author-detail', args=[author.pk])+'?include=bio')
44+
data = load_json(response.content)
45+
assert 'included' not in data
46+
# Second author does
47+
bio = author_bio_factory()
48+
response = client.get(reverse('author-detail', args=[bio.author.pk])+'?include=bio')
49+
data = load_json(response.content)
50+
assert 'included' in data
51+
assert len(data['included']) == 1
52+
assert data['included'][0]['attributes']['body'] == bio.body

rest_framework_json_api/renderers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ def extract_included(fields, resource, resource_instance, included_resources):
257257
# For ManyRelatedFields if `related_name` is not set we need to access `foo_set` from `source`
258258
relation_instance_or_manager = getattr(resource_instance, field.child_relation.source)
259259
except AttributeError:
260+
if not hasattr(current_serializer, field.source):
261+
continue
260262
serializer_method = getattr(current_serializer, field.source)
261263
relation_instance_or_manager = serializer_method(resource_instance)
262264

0 commit comments

Comments
 (0)