Skip to content

Primary key optimization doesn't work (null attribtue values) with nested includes #708

Open
@tyler-baetz

Description

@tyler-baetz

I ran into this issue when upgrading to a newer version of django-rest-framework-json-api and it seems like a bug to me, unless there is now a different way that this is meant to be accomplished that I'm not seeing in the documentation. The problem is when providing an include parameter for nested children of a resource (for example, ?include=articles.author), those "grandchild" objects are present in the included but they have no attributes.

I was able to recreate this with a simple setup:
Models

class Page(models.Model):
    pass


class Author(models.Model):
    first_name = models.TextField()
    last_name = models.TextField()


class Article(models.Model):
    page = models.ForeignKey(Page, related_name='articles', on_delete=models.CASCADE)
    author = models.ForeignKey(Author, related_name='articles', on_delete=models.CASCADE)
    title = models.TextField()

Serializers

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = ('id', 'first_name', 'last_name')


class ArticleSerializer(serializers.ModelSerializer):
    author = AuthorSerializer(many=False, read_only=True)

    included_serializers = {
        'author': AuthorSerializer,
    }

    class Meta:
        model = Article
        fields = ('id', 'title', 'author')


class PageSerializer(serializers.ModelSerializer):
    articles = ArticleSerializer(many=True, read_only=True)

    included_serializers = {
        'articles': ArticleSerializer,
    }

    class Meta:
        model = Page
        fields = ('id', 'articles')

The view is just a simple ModelViewSet.

class PageViewSet(ModelViewSet):
    queryset = Page.objects.all()
    serializer_class = PageSerializer

The output of a query /page/?include=articles.author is this:

{
    "data": [
        {
            "type": "Page",
            "id": "1",
            "attributes": {},
            "relationships": {
                "articles": {
                    "data": [
                        {
                            "type": "Article",
                            "id": "1"
                        }
                    ]
                }
            }
        }
    ],
    "included": [
        {
            "type": "Article",
            "id": "1",
            "attributes": {
                "title": "Some Article"
            },
            "relationships": {
                "author": {
                    "data": {
                        "type": "Author",
                        "id": "1"
                    }
                }
            }
        },
        {
            "type": "Author",
            "id": "1",
            "attributes": {
                "first_name": null,
                "last_name": null
            }
        }
    ]
}

The first_name and last_name fields for the included Author are present but have null values, when data exists in the database for this object. This issue seems to have been introduced in django-rest-framework-json-api v2.6.0, as the fields are returned correctly when using 2.5.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions