Custom representation of Streamfield in rest API

守給你的承諾、 提交于 2019-12-03 06:51:27
probabble

As of Wagtail 1.9, you can modify the API representation of the Block in the StreamField by overriding the get_api_representation() method on the Block.

For your example we can override the method on the ImageChooserBlock itself:

class ImageSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = wagtail.wagtailimages.get_image_model()
        fields = ['title', 'file', 'width', 'height', 'file_size']

class APIImageChooserBlock(ImageChooserBlock):
    def get_api_representation(self, value, context=None):
        return ImageSerializer(context=context).to_representation(value)

@wagtail.wagtailsnippets.models.register_snippet
class MySnippetForAPI(models.Model):
    title = models.CharField(max_length=80)
    content = StreamField([
        ('heading', blocks.CharBlock()),
        ('paragraph', blocks.RichTextBlock()),
        ('image', APIImageChooserBlock())
    ])

https://github.com/wagtail/wagtail/blob/b6ee2db6ac8dbf4b47a81f4b2684b7aca8cc2501/wagtail/wagtailcore/blocks/base.py#L244

This isn't a direct answer to your question but the NHS content store app is solving similar problems and may be a useful reference:

https://github.com/nhsuk/nhsuk-content-store

in particular

https://github.com/nhsuk/nhsuk-content-store/blob/master/api/serializers.py

Adding onto the very helpful answer by probabble, you can also use get_rendition inside a StreamField block by adding a SerializerMethodField:

# serializers.py
# Explicitly importing since models are not loaded when serializers initialized

from wagtail.wagtailimages.models import Image as WagtailImage

class WagtailImageSerializer(serializers.ModelSerializer):
    url = serializers.SerializerMethodField()

    class Meta:
        model = WagtailImage
        fields = ['title', 'url']

    def get_url(self, obj):
        return obj.get_rendition('fill-300x186|jpegquality-60').url

# blocks.py

from .serializers import WagtailImageSerializer 

class APIImageChooserBlock(ImageChooserBlock):
    def get_api_representation(self, value, context=None):
        return WagtailImageSerializer(context=context).to_representation(value)

In this example, we only return the title and url of the image.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!