Streamfield 的自定义表示形式 API
Custom representation of Streamfield in rest API
我对这个帖子有几个问题:https://groups.google.com/forum/#!topic/wagtail-developers/Z4oaCIJXYuI
我正在构建一个无头的 Wagtail,它有一个基于 React 的前端,它调用 Wagtail API 来解析 JSON 和显示内容。很基本。
我想知道是否可以自定义静态流场的输出 API。几个例子:
- 根据 wagtaildemo 中的示例获取图像 URL:https://github.com/wagtail/wagtaildemo/blob/api-tweaks/demo/models.py#L713-L716(我让它工作了单个 URLs)
- PageChooserBlock:从目标页面获取一个字段
正如我在上面链接的主题中所读到的,Wagtail API v1 尚未准备好在其中自定义 Streamfield 的表示形式。
自 v2 以来它有变化吗? (我没有注意到变更日志中的任何相关内容)
如果没有,有没有人对我如何实现这样的事情有一些提示?
我已经计划构建自定义图像模型以通过调用 api/v2/images/id
获得 URL,但我希望将所有这些都整合到一个 JSON 响应中。
这不是您问题的直接答案,但 NHS 内容商店应用程序正在解决类似的问题,可能是一个有用的参考:
https://github.com/nhsuk/nhsuk-content-store
特别是
https://github.com/nhsuk/nhsuk-content-store/blob/master/api/serializers.py
从 Wagtail 1.9 开始,您可以通过覆盖块上的 get_api_representation()
方法来修改 StreamField 中块的 API 表示。
对于您的示例,我们可以覆盖 ImageChooserBlock 本身的方法:
import wagtail
from rest_framework import serializers
class ImageSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = wagtail.images.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.snippets.models.register_snippet
class MySnippetForAPI(models.Model):
title = models.CharField(max_length=80)
content = StreamField([
('heading', blocks.CharBlock()),
('paragraph', blocks.RichTextBlock()),
('image', APIImageChooserBlock())
])
为 Wagtail 2.0+ 更新了代码
通过添加 SerializerMethodField
:
添加到 StreamField 块内的 very helpful answer by probabble, you can also use get_rendition
# 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)
在这个例子中,我们只 return 图片的标题和 url。
我对这个帖子有几个问题:https://groups.google.com/forum/#!topic/wagtail-developers/Z4oaCIJXYuI
我正在构建一个无头的 Wagtail,它有一个基于 React 的前端,它调用 Wagtail API 来解析 JSON 和显示内容。很基本。
我想知道是否可以自定义静态流场的输出 API。几个例子:
- 根据 wagtaildemo 中的示例获取图像 URL:https://github.com/wagtail/wagtaildemo/blob/api-tweaks/demo/models.py#L713-L716(我让它工作了单个 URLs)
- PageChooserBlock:从目标页面获取一个字段
正如我在上面链接的主题中所读到的,Wagtail API v1 尚未准备好在其中自定义 Streamfield 的表示形式。 自 v2 以来它有变化吗? (我没有注意到变更日志中的任何相关内容) 如果没有,有没有人对我如何实现这样的事情有一些提示?
我已经计划构建自定义图像模型以通过调用 api/v2/images/id
获得 URL,但我希望将所有这些都整合到一个 JSON 响应中。
这不是您问题的直接答案,但 NHS 内容商店应用程序正在解决类似的问题,可能是一个有用的参考:
https://github.com/nhsuk/nhsuk-content-store
特别是
https://github.com/nhsuk/nhsuk-content-store/blob/master/api/serializers.py
从 Wagtail 1.9 开始,您可以通过覆盖块上的 get_api_representation()
方法来修改 StreamField 中块的 API 表示。
对于您的示例,我们可以覆盖 ImageChooserBlock 本身的方法:
import wagtail
from rest_framework import serializers
class ImageSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = wagtail.images.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.snippets.models.register_snippet
class MySnippetForAPI(models.Model):
title = models.CharField(max_length=80)
content = StreamField([
('heading', blocks.CharBlock()),
('paragraph', blocks.RichTextBlock()),
('image', APIImageChooserBlock())
])
为 Wagtail 2.0+ 更新了代码
通过添加 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)
在这个例子中,我们只 return 图片的标题和 url。