3
votes

In my wagtail application I have a streamfield that is used to upload an image using ImageChooserBlock along with a title and text. That means in the single streamfield I have a title, a text and an image upload inputs. I'm trying to get the image url in the rest framework's pages API (localhost:8000/api/v2/pages/[page-id]). But this pages api only gives the image id of the uploaded images as follows

{
    "type": "avengers",
    "value": {
        "title": "Tony Stark",
        "avengers": [
            {
                "image": 1,            /******* this is the image id returned ********/
                "title": "Iron Man",
                "text": "Iron man is now in framework"
            }
        ]
    },
    "id": "2f27cb24"
} 

If I access the images api(http://localhost:8000/api/v2/images/1/) I'm getting the download_url as follows

{
    "id": 1,
    "meta": {
        "type": "wagtailimages.Image",
        "detail_url": "http://localhost/api/v2/images/1/",
        "tags": [],
        "download_url": "/media/original_images/avenger.jpeg"
    },
    "title": "avenger.jpeg",
    "width": 400,
    "height": 400
}

My question is how I can get the download_url or the image url in the pages API (localhost:8000/api/v2/pages/[page-id])

My streamfields blocks.py for the avengers block is as follows

class AvengersBlock(blocks.StructBlock):

    title = blocks.CharBlock(required=True, help_text="Add your title")

    Avengers = blocks.ListBlock(
        blocks.StructBlock(
            [
                ("image", ImageChooserBlock(required=True)),
                ("title", blocks.CharBlock(required=True, max_length=40)),
                ("text", blocks.TextBlock(required=True, max_length=200))
            ]
        )
    )

    class Meta:  # noqa
        template = "streams/Avengers_block.html"
        icon = "placeholder"
        label = "Avengers"

This stream field is used in a content types model.py as follows

from django.db import models
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
from wagtail.core.fields import StreamField
from wagtail.core.models import Page
from wagtail.api import APIField

from apps.common.streams import blocks

class AvengersPage(Page):

    tempalte = "avengers/avengers_page.html"  

    content = StreamField(
        [
            ("avengers", blocks.AvengersBlock())
        ],
        null=True,
        blank=True,
    )

    subtitle = models.CharField(max_length=100, null=True, blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("subtitle"),
        StreamFieldPanel("content"),
    ]

    api_fields = [
        APIField("subtitle"),
        APIField("content")
    ]

    class Meta:  # noqa

        verbose_name = "Avengers Page"   
1

1 Answers

1
votes

Add this to your AvengersBlock and when you call your API at

/api/v2/pages/?type=home.AvengersPage&fields=content

you should see the JSON you're looking for.


def get_api_representation(self, value, context=None):
        """ Recursively call get_api_representation on children and return as a plain dict """
        dict_list = []
        for item in value["Avengers"]:
            temp_dict = {
                'title': item.get("title"),
                'text': item.get("text"),
                'image_url': item.get("image").file.url
                # any other relevant fields of your model...
            }
            dict_list.append(temp_dict)

        return dict_list