nickb84
nickb84

Reputation: 641

wagtail api how to expose snippets and serialize nested data

the problem is this, i've created a snippet and i want to expose it but i don't know how to serialize nested data. here my code:

models.py

@register_snippet
class TeamMember(ClusterableModel):
    name = models.CharField(max_length=80)
    description = models.CharField(max_length=80)

    panels = [
        FieldPanel('name'),
        InlinePanel('tasks', label=('Tasks')),
    ]

class Task(Orderable):
    team_member = ParentalKey('adm.TeamMember', related_name="tasks")
    task_name = models.CharField(max_length=80)

endpoints.py

class TeamMemberAPIEndpoint(BaseAPIViewSet):

    model = TeamMember

    body_fields = BaseAPIViewSet.body_fields + [
        'name',
        'description',
        'tasks',
    ]

    listing_default_fields = BaseAPIViewSet.listing_default_fields = [
        'name',
        'description',
        'tasks',
    ]

the result is:

    "items": [
        {
            "name": "python team",
            "description": "",
            "tasks": [
                {
                    "id": 1,
                    "meta": {
                        "type": "adm.Task"
                    }
                },
                {
                    "id": 2,
                    "meta": {
                        "type": "adm.Task"
                    }
                }
            ]
        }

how can i resolve this problem?

Upvotes: 1

Views: 1140

Answers (1)

borisbrue
borisbrue

Reputation: 46

You have several ways to get the nested data.

  1. provide a dedicated serializer for the nested items within the API Endpoint.

  2. the wagtail way. Define additional api properties.


from rest_framework import serializers
from wagtail.api import APIField


class Task(Orderable):
    team_member = ParentalKey('adm.TeamMember', related_name="tasks")
    task_name = models.CharField(max_length=80)

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = (
            "id",
            "task_name",
        )

@register_snippet
class TeamMember(ClusterableModel):
    name = models.CharField(max_length=80)
    description = models.CharField(max_length=80)

    panels = [
        FieldPanel('name'),
        InlinePanel('tasks', label=('Tasks')),
    ]

   api_fields = [
        APIField("tasks", serializer=TaskSerializer(many=True)),
    ]

the response looks like this:

{
    "meta": {
        "total_count": 1
    },
    "items": [
        {
            "name": "Member 1",
            "tasks": [
                {
                    "id": 1,
                    "task_name": "Do this"
                },
                {
                    "id": 2,
                    "task_name": "Do that"
                }
            ]
        }
    ]
}

Upvotes: 3

Related Questions